1

Simple code which init Loader in onCreate() and restart Loader when button pressed. Regarding android documentation getLoaderManager().restartLoader() should start a new loader or restarts an existing Loader in this manager. But each time when I press button and invoke restartLoader it creates new AbstractLoader.

LoaderManager.restartLoader() in Android documentation

public class MainActivity extends Activity implements LoaderCallbacks<String>{

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    getLoaderManager().initLoader(1, null, this); //id is the same
}

@Override
public android.content.Loader<String> onCreateLoader(int id, Bundle args) {
    return new AbstractLoader(this);
}

@Override
public void onLoadFinished(android.content.Loader<String> arg0, String arg1) {
    // TODO Auto-generated method stub
}

@Override
public void onLoaderReset(android.content.Loader<String> arg0) {
    // TODO Auto-generated method stub
    
}

public void click(View v){ //button clicked
    getLoaderManager().restartLoader(1, null, this); //id is the same
}
}

Here is AbstractLoader code:

public class AbstractLoader extends AsyncTaskLoader<String>{

public AbstractLoader(Context context) {
    super(context);
}

 String mResult;

    @Override public String loadInBackground() {
        if (mResult == null) {
            mResult = "Test_String";
        }


        return mResult;
    }

    @Override public void deliverResult(String apps) {
        if (isReset()) {
            if (apps != null) {
                onReleaseResources(apps);
            }
        }
        mResult = apps;

        if (isStarted()) {
            super.deliverResult(apps);
        }

    }

    @Override protected void onStartLoading() {
        Log.e("!LOG!", "onStartLoading " + mResult); //mResult is null each time
        if (mResult != null) {
            deliverResult(mResult);
        }


        if (takeContentChanged() || mResult == null) {
            forceLoad();
        }
    }

    @Override protected void onStopLoading() {
        cancelLoad();
    }

    @Override public void onCanceled(String apps) {
        super.onCanceled(apps);

        onReleaseResources(apps);
    }

    @Override protected void onReset() {
        super.onReset();

        onStopLoading();

        if (mResult != null) {
            onReleaseResources(mResult);
            mResult = null;
        }
    }

    protected void onReleaseResources(String apps) {
    }

}

I need mResult value because I want to load data only once in 5 minutes in another case i want to return previous result. My question is: Why loader is recreated with "restart" even if I created one with the same ID in onCreate with initLoader. Thanks

Community
  • 1
  • 1
p37td8
  • 1,287
  • 2
  • 9
  • 20

1 Answers1

1

It's kind of ambiguous as to exactly what happens based on the method names, but I'd think this line from the docs is explaining the behavior you describe:

If a loader with the same id has previously been started it will automatically be destroyed when the new loader completes its work. The callback will be delivered before the old loader is destroyed.

I'm not exactly sure how this works under the hood, but it sounds like the restartLoader() method will create a new Loader, grab fresh data, and then allow you to potentially merge in or otherwise interact with the old Loader's data before it goes away, as opposed to initLoader which will only allow for the fetching of new info.

I think the method that can help you is onContentChanged(), which will grab new data for the Loader. You can use the LoaderManager's getLoader(int) method to grab a reference to the Loader you've started to and call that method trigger your refresh.

Edit: Originally suggested using startLoading() as an alternative to onContentChanged(), but, per the docs, that shouldn't be called when using a LoaderManager. forceLoad() is also a possibility, but I'd suggest using onContentChanged() as that's what I've had success with in the past.

MattDavis
  • 5,158
  • 2
  • 23
  • 35