is destroyed. Context Leak Protection Running on the Application Context not on an Activity Context. Data Caching No need to re-run the asynchronous task after configuration change. Throttable Can set Throttle so that the requests are not issued too frequently. Cons Complicated!
to the Activity/Fragment when its configuration is changed and re- created. It is especially useful when the screen is rotated while data is being fetched. from Efficient Android Threading
in Fragment#onCreate(). @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); // In support library r8, calling initLoader for a fragment in a FragmentPagerAdapter // in the fragment's onCreate may cause the same LoaderManager to be dealt to multiple // fragments because their mIndex is -1 (haven't been added to the activity yet). Thus, // we do this in onActivityCreated. this.setListShown(false); this.getLoaderManager().initLoader(LOADER_ID_CATEGORIES, this.getArguments(), this); ...
use deliverResult() instead. public abstract class CustomAsyncTaskLoader extends AsyncTaskLoader<Data> { @Override public Data loadInBackground() { if (this.mListener != null) { // Notify the loading status is changed. this.mListener.onLoadStarted(this); } ... } } public class SampleActivity extends Activity { @Override public void onLoadStarted(final CustomAsyncTaskLoader<Data> loader) { if (!this.isFinishing() && loader instanceof CustomAsyncTaskLoader) { this.runOnUiThread(new Runnable() { @Override public void run() { SampleActivity.this.onLoadingStatusChanged(LoadingStatus.LOADING); } }); } }
not be executed. It is not called when reset() is executed just after loadInBackground(). public abstract class CustomAsyncTaskLoader extends AsyncTaskLoader<Data> { private int mNextPage; @Override public Data loadInBackground() { // Fetch data on the next page ... return data; } // If the AsyncTaskLoader is canceled after loadInBackground(), this method is not called. @Override public void deliverResult(Data data) { if (data != null) { // Should increment the page number here. Not do that in loadInBackground()! this.mNextPage++;
data and deliver it to the Activity/Fragment if it is not delivered yet when it starts. Code is at https://gist.github.com/hkurokawa/c61b3d7805aa74d9d111#file- cachedasynctaskloader-java public abstract class CachedAsyncTaskLoader<T> extends AsyncTaskLoader<T> { private T mCached; @Override protected void onStartLoading() { // Return the cached data if exists if (this.mCached != null) { deliverResult(this.mCached); return; } // If data source is changed or cached data is null, try to get data if (this.mCached == null) { this.forceLoad(); }
appends the retrieved data in the next page to the current list and delivers the entire list. Code is at https://gist.github.com/hkurokawa/c61b3d7805aa74d9d111#file- paingasynctaskloader-java public class PagesLoader extends AsyncTaskLoader<Page> { private static final int NUM_ARTICLES_PER_PAGE = 20; private boolean mHasMoreResults; private Page mPage; public PagesLoader(Context context) { super(context); this.mPage = new Page(null, null); this.mHasMoreResults = true; } @Override public Page loadInBackground() { if (this.hasMoreResults()) { // Use mPage.getNextToken() to retrieve the next page. Page response = retrieveNextPage(this.mPage.getNextToken(), NUM_ARTICLES_PER_PAGE); List<Article> articles = response.getArticles();
is valuable in some situations. AsyncTaskLoader is very rather complicated and not easy to take advantage of. RxJava/RxAndroid might be better choice to achieve asynchronous task these days.