Android - onLoadFinished not called

11,550

Solution 1

I have finally found the solution to this problem thanks to the discussion on

https://groups.google.com/forum/#!topic/android-developers/DbKL6PVyhLI

public static <T> void initLoader(final int loaderId, final Bundle args, final LoaderCallbacks<T> callbacks,
        final LoaderManager loaderManager) {
    final Loader<T> loader = loaderManager.getLoader(loaderId);
    if (loader != null && loader.isReset()) {
        loaderManager.restartLoader(loaderId, args, callbacks);
    } else {
        loaderManager.initLoader(loaderId, args, callbacks);
    }
}

In addition as of support library 28 make sure that you don't call initLoader from within Fragment.onCreate(). As the updated documentation states

You typically initialize a Loader within the activity's onCreate() method, or within the fragment's onActivityCreated() method.

see https://developer.android.com/guide/components/loaders

Solution 2

RaB solution dont work for me

My worked Solution, was always destroy Loader before restart

Loader<Cursor> loader = mLoaderManager.getLoader(mKeyLoader);
if (loader != null)
{
    mLoaderManager.destroyLoader(mKeyLoader);
}
mLoaderManager.restartLoader(mKeyLoader, args, this);

Solution 3

In addition to RaB's answer, if you are using a custom Loader, make sure that if you call super if you overwrite deliverResult():

@Override
public void deliverResult(D data) {
    super.deliverResult(data); // <--onLoadFinished() will not be called if you don't call this
    ...
}

Solution 4

fwiw, I had a similar problem from attempting to immediately restart the loader a second time, before the first onLoadFinished was called, resulting in neither being called.

this worked for me:

if( loader == null )
    loader = loaderMngr.initLoader(
        0, null, myLoaderCallbacks
        ); 
else if( loader.isAbandoned() )
    return;
else
    loaderMngr.restartLoader(
        0, null, myLoaderCallbacks
        );    

Solution 5

Check the support library.Use this import android.support.v4.app. Don't use android.app.loadermanager.

import android.support.v4.app.LoaderManager;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;

Initialize part

    LoaderManager mLoaderManager=getSupportLoaderManager(); 

      LoaderManager.LoaderCallbacks<Cursor> mCursorLoaderCallbacks=new LoaderManager.LoaderCallbacks<Cursor>() {
                @Override
                public Loader<Cursor> onCreateLoader(int id, Bundle cursor) {
                      return new CursorLoader(getActivity(), MediaStore.Video.Media.EXTERNAL_CONTENT_URI, COLUMNS_OF_INTEREST, null, null,
                            MediaStore.Video.Media.DATE_ADDED + " DESC");
                }
                @Override
                public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
                }


                @Override
                public void onLoaderReset(Loader<Cursor> loader) {              
               }
            };

  mLoaderManager.initLoader(URL_LOADER_EXTERNAL, null, mCursorLoaderCallbacks);
Share:
11,550
petlack
Author by

petlack

Updated on June 09, 2022

Comments

  • petlack
    petlack almost 2 years

    I am facing an issue with Loader.

    I have an Activity, which displays list of records retrieved from local DB. When the activity starts, records are automatically loaded via LoaderManager.initLoader() method.

    There is also possibility to manually refresh the list via refresh button in ActionBarSherlock. However, after finishing another activity which adds a record to DB, onLoadFinished is not called.

    I am using SimpleCursorLoader and here is code snippet from the activity:

    @Override
    public void onStart() {
       ...
       getSupportLoaderManager().initLoader(0, null, this);
    }
    
    @Override
    public void onPause() {
       ...
       getSupportLoaderManager().destroyLoader(0);
    }
    
    public void refreshRecords() {
       getSupportLoaderManager().restartLoader(0, null, this);
    }
    
    @Override
    public Loader<Cursor> onCreateLoader(int id, final Bundle args) {
    Loader<Cursor> l = new SimpleCursorLoader(this) {
        @Override
        public Cursor loadInBackground() {
            return recordDAO.getCursor();
        }
    };
    l.forceLoad();
    return l;
    }
    
    @Override
    public void onLoadFinished(Loader<Cursor> loader, Cursor c) {
       // updateUI
    }
    
    @Override
    public void onLoaderReset(Loader<Cursor> loader) {
    }
    

    The issue is that after finishing the other activity, onLoaderCreate is called, but onLoaderFinished is not called.

    after some debugging, I've found that SimpleCursorAdapter.deliverResults() is also called, bud ends up on .. if (isReset()) { ..

    Am I missing something? How to force the reload of data?

    Thank you in advance

  • Andrei Aulaska
    Andrei Aulaska almost 11 years
    Works for me. Thank you.
  • Pascal
    Pascal almost 9 years
    Almost the correct solution: as mentioned on groups.google.com/forum/#!topic/android-developers/DbKL6PVyh‌​LI (and I experimented it), the reset condition is !loader.isReset() , i.e., 'You should only restart the loader if the loader is NOT reset.' (written by Etienne). Please update your answer.
  • MistaGreen
    MistaGreen almost 8 years
    Thanks. I finally found a why to force loader always call onLoadFinished method.
  • Reejesh PK
    Reejesh PK almost 5 years
    Worked. Thanks!