Loader簡介以及CursorLoader的使用

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,接下來兩個方法也是如此。因爲最近在學習代碼,看過好幾種使用方法,所以記錄一下。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章