Loader簡介
Loader是一種封裝特別好的異步加載資源的方式,我們可以通過繼承AsyncTaskLoader或者Loader來實現我們的異步加載資源,也可以通過谷歌原生的子類來實現一些簡單的異步資源加載,比如CursorLoader就比較適用於加載數據庫,ContentProvider或者手機中的圖片聯繫人等資源。
CursorLoader的使用
爲了更好的體驗Loader的強大,我們可以嘗試一下使用CursorLoader,然後再深入學習一下
AsyncTaskLoader的使用以及實現機制。
通過將對應的 URI 以及其他的查詢條件傳遞給CursorLoader及其子類,便可讓其在後臺高效地加載數據,等數據加載完成了便會返回一個 Cursor.,然後我們通過實現Loadermanager.LoaderCallbacks接口,在onLoadFinished(final Loader loader, final Cursor data)中取到我們需要的數據。
首先我們需要對CursorLoader繼承,實現其子類,並且實現構造器,如下:
Public class ChildOfCursorLoader extend CursorLoader {
public BoundCursorLoader( final Context context, final Uri uri,
final String[] projection, final String selection, final String[] selectionArgs,
final String sortOrder) {
super(context, uri, projection, selection, selectionArgs, sortOrder);
}
}
當然我們可以將其查詢等條件設置爲靜態變量,如果是這樣的話,我們可以看出一個子類只可以實現一種查詢操作,在這種情況下我們可以使用單例模式,這樣可以節省我們的內存空間,至於是懶漢還是餓漢,根據情況選擇,同時要注意多線程模式下要保證安全。
當然最好還是不指定的方式更好一些,這樣更加靈活,我們可以Loadermanager.LoaderCallbacks接口中的onCreateLoader()中定製自己的查詢條件。
LoaderCallbacks
緊接着我們通過實現Loadermanager.LoaderCallbacks接口來加載數據。
先來了解一下這個接口的函數有哪些:
LoaderManager.LoaderCallbacks 接口包括以下方法:
onCreateLoader(int id,final Bundle args):針對指定的 ID 進行實例化並返回新的 Loader,當我們嘗試訪問加載器時(例如,通過LoaderManager. initLoader()),該方法將檢查是否已存在由該 ID 指定的加載器。如果沒有,它將觸發 LoaderManager.LoaderCallbacks 中的 onCreateLoader() 方法。在此方法中,我們可以創建加載器,通過這個方法將返回 CursorLoader,但我們也可以實現自己的 Loader 子類。
onLoadFinished():將在先前創建的加載器完成加載時調用,當先前創建的加載器完成加載時,將會調用此方法。該方法必須在爲此加載器提供的最後一個數據釋放之前調用。此時,我們應該移除所有使用的舊數據(因爲它們很快就會被釋放),但不要自行釋放這些數據,因爲這些數據歸加載器所有,加載器會處理它們。
onLoaderReset():當創建好的Loader被reset時調用此方法,會清空已綁定數據,此時CreatLoader會重新執行。
以下爲實現接口的代碼:
Public class myLoaderCallback implements Loadermanager.LoaderCallbacks<Cursor> {
@overide
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
Uri baseUri;
if (mCurFilter != null) {
baseUri = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
Uri.encode(mCurFilter));
} else {
baseUri = Contacts.CONTENT_URI;
}
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");
}
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
Mdata = data;
}
public void onLoaderReset(final Loader<Cursor> generic) {
mlistener.onDataCursorUpdated(generic);
}
}
通過上述代碼我們可以看到,我們可以通過onCreateLoader()定製自己所需要的loader,從onLoadFinished中獲取數據,最後在onLoaderReset()中獲取更新後的Loader,然後對原本的數據進行處理。之後只需要兩條代碼就可以完成我們所需要的跟中查詢。
LoaderManager mLoaderManager = getLoaderManager();
mLoaderManager.initLoader(LoaderId,null,callbacks);
值得注意的是getLoaderManager()這個方法通過activity或者Fragment的子類對象纔可以調用。
這樣我們就可以在callbacks.onLoadFinished(Loader loader, Cursor data)中獲取數據,其參數data就是我們需要的數據。
如果對如何使用存在疑問的可以看一下這篇文章:
https://juejin.im/post/5a27c56e51882535cd4ab5af#heading-4
拓展
我們在使用Loader的時候,也可以結合工廠模式使用,就只需要在LoaderCallback通過一些簡單的條件判斷需要create哪種Loader,接下來兩個方法也是如此。因爲最近在學習代碼,看過好幾種使用方法,所以記錄一下。