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.
Leveraging Loaders
Steps:
- Create a Loader ID
- Fill-in Loader Callbacks
- 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