0

I am building an application which is dynamically populating/depopulating arraylist depending on Futuretask thread which communicates with server.

Problem is that when i add new object into my arrayadapter and in any way i call notifyDataSetChanged or setNotifyOnChange

(for example after adding item, i also tried make some postadd function which calls notifyDataSetChanged, or even tried adding setNotifyOnChange in adapter constructor, or before adding (adapter.setNotifyOnChange(true)))

in this Futuretask it simply freezes the thread and causes application malfunction. Without notifyonchange when i slide with my finger to call ArrayAdapter's getView() it works, but that is an undesired behavior.

Note: I am accessing the adapter by static variable reference.

Note#2: I dont think creating new adapter over and over again is a smart choice.

/edit:

My remove method looks like this:

public void remove (int itemid) {
        for (ContactItem i : items)
            if (i.ID == itemid)
                items.remove(i);
    }

(and it hangs in the end at the last pharantesis)

Smarty77
  • 1,208
  • 3
  • 15
  • 30

2 Answers2

1
  1. Pass a weak reference to the activity in your other thread, so you don't leak the context.

        WeakReference<Activity> mRef_Activity = new WeakReference<Activity>(activity);
    
  2. From that thread, run the notify update on the ui thread of the main activity.

        final Activity activity = mRef_Activity.get();
        if(activity != null)
            activity.runOnUiThread(new Runnable() {
    
                @Override
                public void run() {
    
                    ArrayAdapter<String>  adapter = activity.getAdapter();
                    adapter.notifyDataSetChanged();
    
                }
            });
    

Note if you are running async task, instead of a callable or runnable, you can just put the notify update in the postExecute of the async, as it is a callback from the main UI thread.

NameSpace
  • 10,009
  • 3
  • 39
  • 40
  • Hello, your answer helped me thank you, but I am also experiencing very strange bug. I also added setNotifyOnChange(false); to adapter constructor so it wont be called implicitly when i attempt to add/remove from the list, but still sometimes this call occurs when i remove and whole app hangs on, when i tap the screen this is what i get. – Smarty77 Nov 04 '14 at 21:39
  • java.lang.IllegalStateException: The content of the adapter has changed but ListView did not receive a notification. Make sure the content of your adapter is not modified from a background thread, but only from the UI thread. Make sure your adapter calls notifyDataSetChanged() when its content changes. [in ListView(2131427350, class android.widget.ListView) with Adapter(class censored.ui.adapters.ContactsAdapter)] – Smarty77 Nov 04 '14 at 21:39
  • The documentation for the function you mention, "If set to false, caller must manually call notifyDataSetChanged() to have the changes reflected in the attached view. The default is true, and calling notifyDataSetChanged() resets the flag to true." Seems you need to reset it after calling notifyDataSetChanged(). – NameSpace Nov 05 '14 at 08:22
0
  1. Using static variable reference means that you should be carefully in the thread. As far as i know, the adapter updates the data only in the UI thread.
  2. One more thing you should know is you should implement the getCount() function to return correct number. I had a problem when my list view does not update my data. even i trigger the onDatasetChange(). I forgot the getCount() function
kidnan1991
  • 366
  • 2
  • 12