在查詢Content Provider發佈的SQLite的數據時,常規的基於Content Resolver和Cursor的查詢是與Activity/Fragment的View繪製同步的。因此,較大的數據量的數據庫操作會影響用戶體驗。下面介紹一種異步的數據庫操作方法——實現LoaderManager.LoaderCallbacks<Cursor>接口。
LoaderManager是java.lang.Object的直接子類,LoaderCallbacks<D>是其內部接口。在Activity中,可以直接使用XxxActivity.this.getLoaderManager()來得到一個LoaderManager實例,以此調用initLoader(int id, Bundle args, LoaderCallbacks<D> callback)來初始化一個基於LoaderManager的異步查詢操作。
使用其對Content Provider(如通話記錄)進行查詢,方便起見,直接在ListActivity中使用:
方法一: ListActivity直接實現LoaderManager.LoaderCallbacks<Cursor>
1、 繼承ListActivity,並實現LoaderManager.LoaderCallbacks<Cursor>,此時必須Override三個方法:
public class MainActivity extends ListActivity implements LoaderManager.LoaderCallbacks<Cursor> {
......
// 創建一個可查詢ContentProvider的loader
public Loader<Cursor> onCreateLoader(int id, Bundle args){
return null;
}
// loader完成查詢時調用,通常用於在查詢到的cursor中提取數據
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
}
// 暫不對其進行重寫
public void onLoaderReset(Loader<Cursor> loader) {
}
}
2、 重寫onCreateLoader、onLoadFinished方法,預設數據的查詢和顯示操作:
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
// 創建一個CursorLoader實例
CursorLoader cl = new CursorLoader( MainActivity.this, CallLog.Calls.CONTENT_URI, null, null, null, null);
return cl;
}
// 要把Cursor中的數據在ListView或ListActivity中顯示,最好使用SimpleCursorAdapter
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
// 用於顯示的ContentProvider數據(參數:from)
String[] from = new String[] {CallLog.Calls.CACHED_NAME, CallLog.Calls.NUMBER};
// 用於顯示的TextView的資源(參數:to)
int[] to = new int[] {R.id.name, R.id.telNumber};
// 創建一個SimpleCursorAdapter,適配name和number數據,其中list_item.xml中必須包含上面id爲name和telNumber的TextView
SimpleCursorAdapter adapter = new SimpleCursorAdapter(MainActivity.this, R.layout.list_item, cursor, from, to);
// 讓ListActivity加載adapter
MainActivity.this.setListAdapter(adapter);
3、 在MainActivity的onCreate方法中初始化loader:
public void onCreate(Bundle savedInstaceState) {
super.onCreate(savedInstanceState);
getLoaderManager().initLoader(0,null,this);
}
4、 在AndroidManifest中加入相應的uses-permission
方法二: Activity不實現LoaderManager.LoaderCallbacks<Cursor>,使用內部類完成(類似OnClickListener接口的實現)
只需要在onCreate方法中,創建一個LoaderManager.LoaderCallbacks<Cursor>的實例即可。
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
// 內部接口實現中的代碼和以上完全一樣
LoaderManager.LoaderCallbacks<Cusor> loaded = new LoaderManager.LoaderCallbacks<Cursor>(){
......
};
// 由於此時的LoaderCallback<D>不再是this,而是上面創建的loaded
getLoaderManager().initLoader(0, null , loaded);
}
以上,代碼量少,電腦上也沒有源碼就不附了。