关于Loader的基础介绍能够参考:http://www.javashuo.com/article/p-wxdvtxrv-hb.html。java
本章主要经过一个简单的例子阐述AsyncTaskLoader的用法和注意事项。git
AsyncTaskLoader是Loader的子类,其内部经过AsyncTask实现数据异步加载。github
步骤一:建立一个Loader类继承AsyncTaskLoader,并实现其相关抽象方法。好比:app
- onStartLoading:注册一些监听器到loader上,而且执行一次forceLoad(); 不然loader不会开始工做。若是建立loader时不须要它马上工做能够不用调用forceLoader。
- loadInBackground:不用说,在这里就是加载数据而且返回,其实这个数据就返回到了LoaderManager的onLoadFinished方法第二个参数
- onStopLoading:中止加载数据,但不要中止监听也不要释放数据,就能够随时重启loader
- onReset:先确保已经中止加载数据了,而后释放掉监听器并设为null
- onCanceled: 在这里能够释放资源,若是是list就不须要作什么了,可是象cursor或者打开了什么文件就应该关闭一下;
- deliverResult:分发数据。
步骤二:获取LoaderMananger:异步
LoaderMananger mananger = getSupportLoaderManager();步骤三:建立LoaderMananger.LoaderCallbacks回调ide
LoaderManager.LoaderCallbacks callbacks = new LoaderManager.LoaderCallbacks() { @Override public Loader onCreateLoader(int id, Bundle args) { Logger.d("onCreateLoader"); NewsLoader loader = new NewsLoader(LoaderActivity.this, mRepository); return loader; } @Override public void onLoadFinished(Loader loader, List<News> data) { for (News news : data) { Logger.d("onLoadFinished title:" + news.getTitle() + " desc:" + news.getDesc()); } } @Override public void onLoaderReset(Loader loader) { Logger.d("onLoaderReset"); } };步骤四:初始化Loader测试
mNewsLoader = (NewsLoader) mLoaderMananger.initLoader(LOADER_ID, null, callbacks);步骤五:启动Loaderthis
mNewsLoader.forceLoad();步骤六:Loader的其余操做spa
mNewsLoader.startLoading(); mNewsLoader.stopLoading(); mNewsLoader.reset(); mNewsLoader.cancelLoad(); mLoaderMananger.restartLoader(); mLoaderMananger.destroyLoader();步骤七:咱们能够在数据源中添加监听接口,在Loader中实现该接口,在该接口中触发某些动做,好比forceLoad或deliveResult。.net
- LoaderMananger.initLoader() -> LoaderCallback.onCreateLoader() -> AsyncTaskLoader.onStartLoading()
- AsyncTaskLoader.forceLoad() -> AsyncTaskLoader.loadInBackground() -> AsyncTaskLoader.deliverResult() -> OnLoadCompleteListener.onLoadComplete() -> LoadCallback.onLoadFinish()
- AsyncTaskLoader.deliverResult() -> OnLoadCompleteListener.onLoadComplete() -> LoadCallback.onLoadFinish()
在更新数据的时候,咱们能够调用forceLoad,这样就会从loadInBackground方法中获取数据;也能够直接调用deliverResult,将数据传入。
这两种方法能够用在不一样的场景。好比forceLoad,适合在loadInBackground中有接口获取数据的状况下;deliverResult则适合在前面提到的步骤七,若是数据有更新,触发了回调,咱们能够在回调中deliveResult将数据传入。
还有一点很是重要,前面两种方法不论哪一种都会走到deliverResult,传入deliverResult的对象必须是新建的。
LoaderMananger中有个LoaderInfo类,它是OnLoadCompleteListener的实现,deliverResult会调用到LoaderInfo的onLoadComplete(),这个方法中有这么一段代码:
// Notify of the new data so the app can switch out the old data before // we try to destroy it. if (mData != data || !mHaveData) { mData = data; mHaveData = true; if (mStarted) { callOnLoadFinished(loader, data); } }data是咱们经过deliverResult传入的对象,mData是LoaderInfo中一直持有的原对象。只有在这两个对象不同时才会执行onLoadFinish方法。因此若是咱们已经调用过deliverResult传入过数据,以后在loader中仅是改变data的值再传入,mData和data的值永远是同样的,这样就会形成第一次forceLoad(或deliveResult)时会触发onLoadFinish,再调用一次就不会触发。因此咱们须要注意,传递给deliverResult的参数好比是新建的对象。能够是局部新new的变量,也能够每次都使用clone传入。这两种方法经测试均可行且不会引发内存泄露。
Loader中有不少方法能够复写,AsyncTaskLoader中提供了不少Loader的抽象方法实现,也提供了一些新的方法,好比loadInBackground,也均可以复写,灵活性较高。使用的时候咱们要阅读其源码搞清楚调用流程,再根据本身的项目须要,复写相关的方法。