官方建議我們可以使用 CursorLoader 在背景進行非同步的查詢
然後再將結果送回 activity
而當資料改變時 CursorLoader 也會自動重新進行查詢
(以下的範例是使用 support library 的 CursorLoader 版本)
要使用 CursorLoader 必須實作 LoaderManager.LoaderCallbacks interface
為了獲得像 Fragment 一樣的 CursorLoader 支援,範例這裡我們繼承 FragmentActivity
然後在得到查詢條件後使用 LoaderManager.initLoader() 進行初始化
(LoaderManager 透過 Fragment 的 getLoaderManager() 或 support 版的 getSupportLoaderManager())
如果不須查詢條件也可以直接在 onCreate 或 onCreateView 裡直接初始化
public class PhotoThumbnailFragment extends FragmentActivity implements
LoaderManager.LoaderCallbacks<cursor> {
...
private static final int URL_LOADER = 0; //loader 的給定 ID
public String[] mFromColumns = { DataProviderContract.IMAGE_PICTURENAME_COLUMN };
public int[] mToFields = { R.id.PictureName };
...
public View onCreateView(LayoutInflater inflater, ViewGroup viewGroup, Bundle bundle) {
...
// 初始化 CursorLoader. The URL_LOADER 最後會傳入 onCreateLoader()
getSupportLoaderManager().initLoader(URL_LOADER, null, this);
...
ListView mListView = (ListView) findViewById(R.id.dataList);
SimpleCursorAdapter mAdapter =
new SimpleCursorAdapter(
this, // Current context
R.layout.list_item, // Layout for a single row
null, // No Cursor yet
mFromColumns, // Cursor columns to use
mToFields, // Layout fields to use
0 // No flags
);
mListView.setAdapter(mAdapter);
}
...
// 當系統把Loader 初始化並準備好進行查詢時會呼叫 onCreateLoader 這個 Callback
@Override
public Loader<cursor> onCreateLoader(int loaderID, Bundle bundle){
//依照 loaderID 進行處理
switch (loaderID) {
case URL_LOADER:
// 回傳 CursorLoader,當查詢完成時會呼叫 onLoadFinished()
return new CursorLoader(
this, // Parent activity context
mDataUrl, // Table to query
mProjection, // Projection to return
null, // No selection clause
null, // No selection arguments
null // Default sort order
);
default:
// 不合理的 id 就回傳 null
return null;
}
}
...
// 完成查詢時會呼叫 onLoadFinished
@Override
public void onLoadFinished(Loader<cursor> loader, Cursor cursor) {
...
//更新 cursor
mAdapter.changeCursor(cursor);
}
...
// 如果資料改變則 onLoaderReset 會被呼叫
@Override
public void onLoaderReset(Loader<cursor> loader) {
// 把 adapter 中 Cursor 的 reference 清掉,防止 memory leaks.
mAdapter.changeCursor(null);
}
}相關資料:
Loading Data in the Background
Running a Query with a CursorLoader
沒有留言:
張貼留言