Android Loader詳細介紹及實例代碼
一,Android裝載器基本方法
裝載器從android3.0開始引進。它使得在activity或fragment中異步加載數(shù)據(jù)變得簡單。裝載器具有如下特性:
- 它們對每個Activity和Fragment都有效。
- 他們提供了異步加載數(shù)據(jù)的能力。
- 它們監(jiān)視數(shù)據(jù)源的一將一動并在內(nèi)容改變時傳送新的結(jié)果。
- 當由于配置改變而被重新創(chuàng)建后,它們自動重連到上一個加載器的游標,所以不必重新查詢數(shù)據(jù)。
裝載器API概述
在使用裝載器時,會涉及很多類和接口們,我們在下表中對它們總結(jié)一下:
Class/Interface |
說明 |
LoaderManager |
一個抽像類,關(guān)聯(lián)到一個Activity或Fragment,管理一個或多個裝載器的實例。這幫助一個應(yīng)用管理那些與Activity或Fragment的生命周期相關(guān)的長時間運行的的操作。最常見的方式是與一個CursorLoader一起使用,然而應(yīng)用是可以隨便寫它們自己的裝載器以加載其它類型的數(shù)據(jù)。 每個activity或fragment只有一個LoaderManager。但是一個LoaderManager可以擁有多個裝載器。 |
LoaderManager.LoaderCallbacks |
一個用于客戶端與LoaderManager交互的回調(diào)接口。例如,你使用回調(diào)方法onCreateLoader()來創(chuàng)建一個新的裝載器。 |
Loader(裝載器) |
一個執(zhí)行異步數(shù)據(jù)加載的抽象類。它是加載器的基類。你可以使用典型的CursorLoader,但是你也可以實現(xiàn)你自己的子類。一旦裝載器被激活,它們將監(jiān)視它們的數(shù)據(jù)源并且在數(shù)據(jù)改變時發(fā)送新的結(jié)果。 |
AsyncTaskLoader |
提供一個AsyncTask來執(zhí)行異步加載工作的抽象類。 |
CursorLoader |
AsyncTaskLoader的子類,它查詢ContentResolver然后返回一個Cursor。這個類為查詢cursor以標準的方式實現(xiàn)了裝載器的協(xié)議,它的游標查詢是通過AsyncTaskLoader在后臺線程中執(zhí)行,從而不會阻塞界面。使用這個裝載器是從一個ContentProvider異步加載數(shù)據(jù)的最好方式。相比之下,通過fragment或activity的API來執(zhí)行一個被管理的查詢就不行了。 |
二,啟動一個裝載器
LoaderManager管理一個Activiry或Fragment中的一個或多個裝載器.但每個activity或fragment只擁有一個LoaderManager.
你通常要在activity的onCreate()方法中或fragment的onActivityCreated()方法中初始化一個裝載器.你可以如下創(chuàng)建:
// 準備裝載器.可以重連一個已經(jīng)存在的也可以啟動一個新的. getLoaderManager().initLoader(0,null, this);
initLoader()方法有以下參數(shù):
- 一個唯一ID來標志裝載器.在這個例子中,ID是0.
- 可選的參數(shù),用于裝載器初始化時(本例中是null).
- 一個LoaderManager.LoaderCallbacks的實現(xiàn).被LoaderManager調(diào)用以報告裝載器的事件,在這個例子中,類本實現(xiàn)了這個接口,所以傳的是它自己:this.
initLoader()保證一個裝載器被初始化并激活.它具有兩種可能的結(jié)果:
- 如果ID所指的裝載器已經(jīng)存在,那么這個裝載器將被重用.
- 如果裝載器不存在,initLoader()就觸發(fā)LoaderManager.LoaderCallbacks的方法onCreateLoader().這是你實例化并返回一個新裝載器的地方.
在這兩種情況中,傳入的LoaderManager.LoaderCallbacks的實現(xiàn)都與裝載器綁定在一起.并且會在裝載器狀態(tài)變化時被調(diào)用.如果在調(diào)用這個方法時,調(diào)用者正處于啟動狀態(tài),并且所請求的裝載器已存在并產(chǎn)生了數(shù)據(jù),那么系統(tǒng)會馬上調(diào)用onLoadFinished()(也就是說在initLoader()還在執(zhí)行時).所以你必須為這種情況的發(fā)生做好準備.
注意initLoader()返回所創(chuàng)建的裝載器,但是你不需保存一個對它的引用.LoaderManager自動管理裝載器的生命.LoaderManager會在需要時開始和停止裝載動作,并且維護裝載器的狀態(tài)和它所關(guān)聯(lián)的內(nèi)容.這意味著,你很少與裝載器直接交互.你通常都是使用LoaderManager.LoaderCallbacks的方法們在某個事件發(fā)生時介入到數(shù)據(jù)加載的過程中.
三,重啟裝載器
當你使用initLoader()時,如果指定ID的裝載器已經(jīng)存在,則它使用這個裝載器.如果不存在呢,它將創(chuàng)建一個新的.但是有時你卻是想丟棄舊的然后開始新的數(shù)據(jù).
要想丟棄舊數(shù)據(jù),你應(yīng)使用restartLoader().例如,下面這個SearchView.OnQueryTextListener的實現(xiàn)在用戶查詢發(fā)生改變時重啟了裝載器,裝載器于是需重啟從而能使用新的搜索過慮來進行一次新的查詢.
<pre name="code" class="html">public boolean onQueryTextChanged(String newText) { // 當動作欄的搜索字串發(fā)生改時被調(diào)用. // 更新搜索過慮,然后重新啟動裝載利用這個新過慮進行新的查詢. mCurFilter = !TextUtils.isEmpty(newText) ? newText : null; getLoaderManager().restartLoader(0, null, this); return true; } <span style="font-family: Arial, Helvetica, sans-serif;">LoaderManager.LoaderCallbacks是一個回調(diào)接口,它使得客戶端可以與LoaderManager進行交互.</span>
裝載器,一般指的是CursorLoader,我們希望在它停止后依然保持數(shù)據(jù).這使得應(yīng)用可以在activity或fragment的 onStop() 和onStart() 之間保持數(shù)據(jù),所以當用戶回到一個應(yīng)用時,它們不需等待數(shù)據(jù)加載.你使用LoaderManager.LoaderCallbacks 的方法們,在需要時創(chuàng)建新的裝載器,并且告訴應(yīng)用什么時候要停止使用裝載器的數(shù)據(jù).
</span></span> LoaderManager.LoaderCallbacks 包含以下方法們: onCreateLoader() —跟據(jù)傳入的ID,初始化并返回一個新的裝載器. onLoadFinished() —當一個裝載器完成了它的裝載過程后被調(diào)用. onLoaderReset() —當一個裝載器被重置而什其數(shù)據(jù)無效時被調(diào)用.
當你試圖去操作一個裝載器時(比如,通過initLoader()),會檢查是否指定ID的裝載器已經(jīng)存在.如果它不存在,將會觸發(fā)LoaderManager.LoaderCallbacks 的方法onCreateLoader().這是你創(chuàng)建一個新裝載器的地方.通常這個裝載器是一個CursorLoader,但是你也可以實現(xiàn)你自己的裝載器.
String mCurFilter; ... public Loader<Cursor> onCreateLoader(int id, Bundle args) { // 這里是在需要創(chuàng)建新裝載器時被調(diào)用的. // 我們只是簡單的擁有一個裝載器,所以我們不需要關(guān)心ID. // First, pick the base URI to use depending on whether we are // currently filtering. Uri baseUri; if (mCurFilter != null) { baseUri = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI, Uri.encode(mCurFilter)); } else { baseUri = Contacts.CONTENT_URI; } // Now create and return a CursorLoader that will take care of // creating a Cursor for the data being displayed. String select = "((" + Contacts.DISPLAY_NAME + " NOTNULL) AND (" + Contacts.HAS_PHONE_NUMBER + "=1) AND (" + Contacts.DISPLAY_NAME + " != '' ))"; return new CursorLoader(getActivity(), baseUri, CONTACTS_SUMMARY_PROJECTION, select, null, Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC"); }
感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!
相關(guān)文章
Android編程實現(xiàn)RotateAnimation設(shè)置中心點旋轉(zhuǎn)動畫效果
這篇文章主要介紹了Android編程實現(xiàn)RotateAnimation設(shè)置中心點旋轉(zhuǎn)動畫效果,結(jié)合實例形式較為詳細的分析了Android xml布局及RotateAnimation動畫類相關(guān)操作技巧,需要的朋友可以參考下2018-02-02Android Studio時間選擇器的創(chuàng)建方法
這篇文章主要為大家詳細介紹了Android Studio時間選擇器的創(chuàng)建方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-10-10JS實現(xiàn)點擊參數(shù)面板按鈕顯示或隱藏數(shù)據(jù)
本文主要介紹JS實現(xiàn)點擊參數(shù)面板按鈕顯示或隱藏數(shù)據(jù)的方法,具有很好的參考價值。下面跟著小編一起來看下吧2017-03-03Fragment通過FragmentManager實現(xiàn)通信功能詳細講解
這篇文章主要介紹了Fragment通過FragmentManager實現(xiàn)通信功能,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習吧2023-01-01Android checkbox的listView(多選,全選,反選)具體實現(xiàn)方法
由于listview的一些特性,剛開始寫這種需求的功能的時候都會碰到一些問題,重點就是存儲每個checkbox的狀態(tài)值,在這里分享出了完美解決方法:2013-06-06