Android 入门笔记(三):Loader

. 2 min read

AsyncTaskLoader is a better choice for Activity-bound thread management, because it handles lifecycle changes correctly, delivering the result to the current active activity, preventing duplication of background threads, and helping to eliminate duplication of zombie activities.

loader

Leveraging Loaders

Steps:

  1. Create a Loader ID
  2. Fill-in Loader Callbacks
  3. Init Loader with LoaderManager

Detail:

1. Create a constant int to uniquely identify the loader;

Implement tne LoaderManager.LoaderCallbacks<> on Activity and override 3 methods(step 2):

public class MainActivity extends AppCompatActivity implements
    LoaderManager.LoaderCallbacks<String> 

2. Override methods and fill-in Loader Callbacks:

@Override
public Loader<String> onCreateLoader(int id, Bundle args) {
	return new AsyncTaskLoader<String>(this) {
	    @Override
	    protected void onStartLoading() {
	    }
	    @Override
	    public String loadInBackground() {
	    }
	};
}

@Override
public void onLoadFinished(Loader<String> loader, String data) {

}

@Override
public void onLoaderReset(Loader<String> loader) {

}

3. Get LoaderManager by calling getSupportLoaderManager;

Get Loader by calling getLoader and passing the ID; Pass data to loader by bundle:

Bundle bundle = new Bundle();
bundle.putString("KEY", "VALUE");
LoaderManager loadManager = getSupportLoaderManager();
Loader<String> loader = loadManager.getLoader(LOADER_ID);
if (loader == null)
    loadManager.initLoader(LOADER_ID, bundle, this);
else
    loadManager.restartLoader(LOADER_ID, bundle, this);

Caching With Loaders

1. Create a cache member variable in your AsyncTaskLoader implementation.

Override deliverResult() so that save the fetched data in your cache first, before you call the superclass's implementation of deliverResult().

String cache;
@Override
public void deliverResult(String data) {
    this.cache = data;
    super.deliverResult(data);
}

2. In onStartLoading() check if there's cached data, and if so, let your AsyncTaskLoader just deliver that. Otherwise, start loading.

@Override
protected void onStartLoading() {
    /*do something here*/
    //If mGithubJson is not null, deliver that result.
    //Otherwise, force a load. 
    if (mGithubJson != null) {
      	/** I think we could call onLoadFinished directly,
            and it works for me well!**/
        //onLoadFinished(this, cache);
        deliverResult(cache);
    }else {
        forceLoad();
    }
}

Need more ? see here