關於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,也均可以複寫,靈活性較高。使用的時候咱們要閱讀其源碼搞清楚調用流程,再根據本身的項目須要,複寫相關的方法。