Skip to content Skip to sidebar Skip to footer

How Can I Update An Adapter Of An Activity From Other Activity?

Problem: Activity A is a ListView that contains a ListAdapter, and clicking in any item of the adapter leads to activity B. Activity B has a button that fetches a new item (or seve

Solution 1:

Don't save static references to the adapter. It will indeed leak memory and behave badly.

It appears I misunderstood the first time. Here is an updated answer:

First solution

The prettiest solution is to implement a content provider for the data storage and query that content provider in both A and B. Update the data in B using contentProvider.insert() and read the data using contentProvider.query() returning for example a SQLiteCursor if it is backed by database or a MatrixCursor if you just save it in memory in the content provider.

The basic steps (without CursorLoader):

  1. In onCreate of A you register yourself as a contentobserver using ContentResolver.registerContentObserver(uri, true, this) where uri is an URI using some scheme you set.
  2. In onCreate of A you get the data by querying the contentprovider using ContentResolver.query(uri, projection, selection, selectionArgs, sortOrder) where projection, selection, selectionArgs and sortOrder can be what fits your contentprovider (maybe null). Uri refers to the data you want to query and is your choice.
  3. When data is loaded in B you call ContentResolver.insert(). In insert of your contentprovider you call ContentResolver.notifyChange (Uri uri, null, null) where uri is the URI you used in step 1.
  4. Implement onChange(boolean selfChange) in A and requery the content provider when it is called.

Note that you will not need to call registerContentObserver at all if you use CursorLoaders! It will receive the new cursor in the loader since it has automatic requery when you notify change.

Second solution A less pretty solution is to implement a singleton object that handles the data. Something like:

  1. Implement the class

    publicclassDataHolder {
        privatestaticDataHolder sDataHolder;
    
        privateString data = ""; // Data represented by string.publicDataHoldergetInstance() {
            if (sDataHolder == null) {
                sDataHolder = newDataHolder()
            }
            return sDataHolder;
        }
    
        privateDataHolder() {} // Hidden constructorpublicvoidsetData(final String data) {
            mData = data;
    
            for (DataListenerlistener: mDataListeners) {
                listener.onDataChanged(mData);
            }
        }
    
        publicvoidregisterListener(DataListener listener) {
           mDataListeners.add(listener);
        }
    
        publicStringunregisterListener(DataListener listener) {
           mDataListeners.remove(listener);
        }
    
        publicStringgetData() {
           return mData;
        }
    
        publicstaticinterfaceDataListener {
            publicvoidonDataChanged(String data);
        }
    }
    
  2. Make A implement DataListener
  3. Read and update the data in onStart() of DataListener to make sure that it is set if the change was done when B was alive using DataHolder.getInstance().getData().
  4. Register listener in A's onCreate/onStart using DataHolder.getInstance().registerListener(this); Let the listener update the data.
  5. Unregister listener in A's onDestroy/onStop using DataHolder.getInstance().unregisterListener(this)
  6. Set the data and signal any listener in B using DataHolder.getInstance().setData(data)

Also note that you can make the second solution fully thread safe by changing void registerListener() to synchronized String registerListenerAndGetValue() if you also make setValue synchronized.

Old answer based on a misunderstanding

My old answer for general result handling did not quite answer the question, but it was:

If you want to send data back to an activity A you should do the following:

  1. Always start B with startActivityForResult (Intent intent, int requestCode)
  2. Set the result when done in B using setResult (int resultCode)
  3. Handle the result when you come back to A by implementing onActivityResult (int requestCode, int resultCode, Intent data)

As an addition you could add so you only fetch data in A the first time by doing it only if savedInstanceState == null in for example onCreate().

Solution 2:

try calling mListView.invalidate();

**java-doc

Invalidate the whole view. If the view is visible, onDraw(android.graphics.Canvas) will be called at some point in the future. This must be called from a UI thread. To call from a non-UI thread, call postInvalidate().

Post a Comment for "How Can I Update An Adapter Of An Activity From Other Activity?"