Difference between restartLoader and onContentChanged
Asked Answered
D

3

6

Currently, I have a loader

@Override
public Loader<List<HomeMenuRowInfo>> onCreateLoader(int arg0, Bundle bundle) {
    return new HomeMenuRowInfosLoader(this.getSherlockActivity());
}

Sometimes, I need to ask the loader to reload again, due to content changes. I will do this.

this.getLoaderManager().getLoader(0).onContentChanged();

However, I would like to pass some additional bundle information to the onCreateLoader callback when the content changes. I realize by using onContentChanged, there is no way to do so.

The only way I can figure out is

this.getLoaderManager().restartLoader(0, bundle, this);

I was wondering, is there any major differences in Loader behavior, of using restartLoader instead of onContentChanged, besides the ability to pass in bundle?

Dissuasion answered 24/5, 2013 at 5:32 Comment(0)
P
4

I think, the major difference is that the restartLoader method destroys the old loader that has the same ID and starts a new one while the onContentChanged method either forces the loader to load (forceLoad) or simply sets a flag that indicates the content has changed while the loader was stopped. In the second case the 'owner' of the loader remains responsible for its (re)loading after the content has changed. I assume this is done automatically by the loaderManager as in the restartLoader case.

If you decide to use the restartLoader method you should keep in mind the destruction of the old loader and the possible implications for your application, like slow re-initializations and so on.

You can take a look at the methods documentation for more info - restartLoader and onContentChanged

Also note that the old loader is destroyed when the new one finishes its work

Pitchblack answered 10/3, 2014 at 11:53 Comment(0)
V
1

State diagram should help with understanding how to use API. First time I also spent a lot of minutes for making picture clear. Use my work!

Article: https://plus.google.com/117981280628062796190/posts/8b9RmQvxudb

Loader States Diagram

Venezuela answered 13/2, 2015 at 12:16 Comment(0)
U
0

call restartLoader every time you want fresh data or you want to change your arguments for the cursor.

If you use initLoader to load data

lm = fragment.getLoaderManager();
lm.initLoader(LOADER_ID_LIST, null, this);

Each call to initLoader will return the same cursor to onLoadFinished. The onCreateLoader method will only be called on the 1st call to initLoader. Hence you can't change the query. You get the same cursor same data to the onLoadFinished method.

@Override
public void onLoadFinished(
        android.support.v4.content.Loader<Cursor> loader, Cursor cursor) {
    switch (loader.getId()) {
    case LOADER_ID_LIST:
        // The asynchronous load is complete and the data
        // load a list of
        populateFromCursor(cursor);
        break;
    case LOADER_ID_ENTRY:
        populateFromCursor(cursor);
        break;
    }
    // The listview now displays the queried data.
}

So to get new cursor data to onLoadFinished use restartLoaderand you can pass in bundle info if you want. Below I'm passing null because there's a global variable available.

lm = fragment.getLoaderManager();
lm.restartLoader(LOADER_ID_LIST, null, this);

The loaderManager will then call the onCreateLoaderMethod.

@Override
public android.support.v4.content.Loader<Cursor> onCreateLoader(int id,
        Bundle args) {

    android.support.v4.content.Loader<Cursor> ret = null;

    // Create a new CursorLoader with the following query parameters.
    switch (id) {

    // load the entire list
    case LOADER_ID_LIST:
        String sortOrder = null;
        switch (mSortOrder) {
        case 0:
            sortOrder = RidesDatabaseHandler.KEY_DATE_UPDATE + " desc";
            break;
        case 1:
            sortOrder = RidesDatabaseHandler.KEY_ID + " desc";
            break;
        case 2:
            sortOrder = RidesDatabaseHandler.KEY_NAME;
        }
        return new CursorLoader(context, RidesDatabaseProvider.CONTENT_URI,
                PROJECTION, null, null, sortOrder);

        // load a single item
    case LOADER_ID_ENTRY:
        sortOrder = null;
        String where = RidesDatabaseHandler.KEY_ID + "=?";

        String[] whereArgs = new String[] { Integer.toString(lastshownitem) };

        return new CursorLoader(context, RidesDatabaseProvider.CONTENT_URI,
                PROJECTION, where, whereArgs, null);
    }
    return ret;
}

Notes: You don't have to call initLoader you can call restartLoader every time that is unless you really want the same data that was returned from previous query. You don't have to call onContentChanged() and in the docs it says the Loader.ForceLoadContentObserver is done for you.

Utopian answered 13/3, 2014 at 14:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.