LoaderManager與CursorLoader用法,cursorloader

來源:互聯網
上載者:User

LoaderManager與CursorLoader用法,cursorloader
一.基本概念

1.LoaderManager
 LoaderManager用來負責管理與Activity或者Fragment聯絡起來的一個或多個Loaders對象.
 每個Activity或者Fragment都有唯一的一個LoaderManager執行個體(通過getLoaderManager()方法獲得),用來啟動,停止,保持,重啟,關閉它的Loaders,這些功能可通過調用initLoader()/restartLoader()/destroyLoader()方法來實現.
 LoaderManager並不知道資料如何裝載以及何時需要裝載.相反,它只需要控制它的Loaders們開始,停止,重設他們的Load行為,在配置變換或資料變化時保持loaders們的狀態,並使用介面來返回load的結果.

 2.Loader
 Loades負責在一個單獨線程中執行查詢,監控資料來源改變,當探測到改變時將查詢到的結果集發送到註冊的監聽器上.Loader是一個強大的工具,具有如下特點
 (1)它封裝了實際的資料載入.
 Activity或Fragment不再需要知道如何載入資料.它們將該任務委託給了Loader,Loader在後台執行查詢要求並且將結果返回給Activity或Fragment.
 (2)用戶端不需要知道查詢如何執行.Activity或Fragment不需要擔心查詢如何在獨立的線程中執行,Loder會自動執行這些查詢操作.
 這種方式不僅減少了代碼複雜度同事也消除了線程相關bug的潛在可能.
 (3)它是一種安全的事件驅動方式.
 Loader檢測底層資料,當檢測到改變時,自動執行並載入最新資料.
 這使得使用Loader變得容易,用戶端可以相信Loader將會自己自動更新它的資料.
 Activity或Fragment所需要做的就是初始化Loader,並且對任何反饋回來的資料進行響應.除此之外,所有其他的事情都由Loader來解決.

二.非同步Loader的實現原理 

(1)執行非同步載入的任務.為了確保在一個獨立線程中執行載入操作,Loader的子類必須繼承AsyncTaskLoader<D>而不是Loader<D>類.
 AsyncTaskLoader<D>是一個抽象Loader,它提供了一個AsyncTask來做它的執行操作.
 當定義子類時,通過實現抽象方法loadInBackground方法來實現非同步task.該方法將在一個背景工作執行緒中執行資料載入操作.
 (2)在一個註冊監聽器中接收載入完成返回的結果.
 對於每個Loader來說,LoaderManager註冊一個OnLoadCompleteListener<D>,該對象將通過調用onLoadFinished(Loader<D> loader, D result)方法使Loader將結果傳送給用戶端.
 Loader通過調用Loader#deliverResult(D result),將結果傳遞給登入的監聽器.

三.Loader三種不同狀態. 

已啟動: 處於已啟動狀態的Loader會執行載入操作,並在任何時間將結果傳遞到監聽器中.已啟動的Loader將會監聽資料改變,當檢測到改變時執行新的載入. 一旦啟動,Loader將一直                    處在已啟動狀態,一直到轉換到已停止和重設,這是唯一一種onLoadFinished永遠都會調用的狀態。
已停止: 處於已停止狀態的Loader將會繼續監聽資料改變,但是不會將結果返回給用戶端.在已停止狀態,Loader可能被啟動或者重啟.
重設:   當Loader處於重設狀態時,將不會執行新的載入操作,也不會發送新的結果,也不會檢測資料變化.
       當一個Loader進入重設狀態,它必須解除對應的資料引用,方便記憶體回收(用戶端也必須確定,在Loader無效之後,移除了所有對該資料的引用).
      通常,重設Loader不會兩次調用.然而,在某些情況下他們可能會啟動,所以如果必要的話,它們必須能夠適時重設.

四.接收Loader資料改變的通知. 

必須有一個觀察者接受資料來源改變的通知.
 Loader必須實現這些Observer其中之一(ContentObserver,BroadcastReceiver等),來檢測底層資料來源的改變.
 當檢測到資料改變,觀察者必須調用Loader#onContentChanged().在該方法中執行兩種不同操作:
 (1)如果Loader已經處於啟動狀態,就會執行一個新的載入操作;

 (2)設定一個flag標識資料來源有改變,這樣當Loader再次啟動時,就知道應該重新載入資料了. 

五.CursorLoader實現LoaderManager.LoaderCallbacks介面方法.介面聲明及使用如下: 

public interface LoaderCallbacks<D> {
  public Loader<D> onCreateLoader(int id, Bundle args);
  public void onLoadFinished(Loader<D> loader, D data);
  public void onLoaderReset(Loader<D> loader);
 }
 
 onCreateLoader方法將在建立Loader時候調用,此時需要提供查詢的配置,如監聽一個URI.
 這個方法會在loader初始化的時調用,即調用下面的代碼時調用:
  getLoaderManager().initLoader(id, bundle, loaderCallbacks);
  initLoader函數原型為:
  <D> Loader<D> android.app.LoaderManager.initLoader(int id, Bundle bundle, LoaderCallbacks<D> loaderCallbacks);
  第1個參數loader的ID,可自訂一個常量值,便於實現多個Loader;
  第2個參數一般置null;
  第3個參數是實現了LoaderManager.LoaderCallbacks實作類別對象.
 onLoadFinished方法,在Loader完成任務後調用,一般在此讀取結果.
 onLoaderReset方法是在配置發生變化時調用,一般調用下面的代碼後調用:
  getLoaderManager().restartLoader(id, bundle, loaderCallbacks);
  restartLoader方法參數同initLoader,重新初始化loader之後,需要用來釋放對前面loader查詢到的結果引用.  

六.一個具體監聽通話記錄的樣本 

在Activity中onCreate調用 

 CallLogsLoaderListener callLogsCallback = new CallLogsLoaderListener(this);
  getLoaderManager().initLoader(0, null, callLogsCallback);
 
 在onDestroy調用
  getLoaderManager().destroyLoader(0);
 
 配置許可權
  <uses-permission android:name="android.permission.WRITE_CALL_LOG" />
  <uses-permission android:name="android.permission.READ_CALL_LOG" />
 
 具體的類實現

import android.app.LoaderManager;import android.content.Context;import android.content.CursorLoader;import android.content.Loader;import android.database.Cursor;import android.database.CursorWrapper;import android.os.Bundle;import android.provider.CallLog;import android.util.Log;public class CallLogsLoaderListener implements        LoaderManager.LoaderCallbacks<Cursor> {    private Context mContext;    public CallLogsLoaderListener(Context context) {        mContext = context;    }    @Override    public Loader<Cursor> onCreateLoader(int id, Bundle args) {        CursorLoader loader = new CursorLoader(mContext,                CallLog.Calls.CONTENT_URI, null, null, null, null) {            @Override            public Cursor loadInBackground() {                Cursor cursor = super.loadInBackground();                if (cursor == null)                    return null;                CallLogsCursor callLogsCursor = new CallLogsCursor(cursor);                return callLogsCursor;            }        };        return loader;    }    @Override    public void onLoadFinished(Loader<Cursor> loader, Cursor data) {    }    @Override    public void onLoaderReset(Loader<Cursor> loader) {    }    public class CallLogsCursor extends CursorWrapper {        public CallLogsCursor(Cursor cursor) {            super(cursor);            int nameIndex = cursor.getColumnIndex(CallLog.Calls.CACHED_NAME);            int numberIndex = cursor.getColumnIndex(CallLog.Calls.NUMBER);            int typeIndex = cursor.getColumnIndex(CallLog.Calls.TYPE);            int dateIndex = cursor.getColumnIndex(CallLog.Calls.DATE);            int durationIndex = cursor.getColumnIndex(CallLog.Calls.DURATION);            // 從遊標的最後索引往前查詢,因為最新的通話記錄在最後            for (cursor.moveToLast(); !cursor.isBeforeFirst(); cursor                    .moveToPrevious()) {                // 姓名                String name = cursor.getString(nameIndex);                // 號碼                String number = cursor.getString(numberIndex);                // 類型                int type = cursor.getInt(typeIndex);                // 日期                long date = cursor.getLong(dateIndex);                // 通話時間長度                int duration = cursor.getInt(durationIndex);                Log.d("debug", "name=" + name + ", number=" + number                        + ", type=" + type + ", date=" + date + ", duration="                        + duration);            }        }    }}

  

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.