編寫:kesenhoo - 原文:http://developer.android.com/training/load-data-background/handle-results.html
正如前面一節(jié)課講到的,你應該在 onCreateLoader()的回調(diào)里面使用CursorLoader執(zhí)行加載數(shù)據(jù)的操作。Loader查詢完后會調(diào)用Activity或者FragmentActivity的LoaderCallbacks.onLoadFinished()將結果回調(diào)回來。這個回調(diào)方法的參數(shù)之一是Cursor,它包含了查詢的數(shù)據(jù)。你可以使用Cursor對象來更新需要顯示的數(shù)據(jù)或者進行下一步的處理。
除了onCreateLoader()與onLoadFinished(),你也需要實現(xiàn)onLoaderReset()。這個方法在CursorLoader檢測到Cursor上的數(shù)據(jù)發(fā)生變化的時候會被觸發(fā)。當數(shù)據(jù)發(fā)生變化時,系統(tǒng)也會觸發(fā)重新查詢的操作。
為了顯示CursorLoader返回的Cursor數(shù)據(jù),需要使用實現(xiàn)AdapterView的視圖組件,,并為這個組件綁定一個實現(xiàn)了CursorAdapter的Adapter。系統(tǒng)會自動把Cursor中的數(shù)據(jù)顯示到View上。
你可以在顯示數(shù)據(jù)之前建立View與Adapter的關聯(lián)。然后在onLoadFinished()的時候把Cursor與Adapter進行綁定。一旦你把Cursor與Adapter進行綁定之后,系統(tǒng)會自動更新View。當Cursor上的內(nèi)容發(fā)生改變的時候,也會觸發(fā)這些操作。
例如:
public String[] mFromColumns = {
DataProviderContract.IMAGE_PICTURENAME_COLUMN
};
public int[] mToFields = {
R.id.PictureName
};
// Gets a handle to a List View
ListView mListView = (ListView) findViewById(R.id.dataList);
/*
* Defines a SimpleCursorAdapter for the ListView
*
*/
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
);
// Sets the adapter for the view
mListView.setAdapter(mAdapter);
...
/*
* Defines the callback that CursorLoader calls
* when it's finished its query
*/
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
...
/*
* Moves the query results into the adapter, causing the
* ListView fronting this adapter to re-display
*/
mAdapter.changeCursor(cursor);
}
當Cursor失效的時候,CursorLoader會被重置。這通常發(fā)生在Cursor相關的數(shù)據(jù)改變的時候。在重新執(zhí)行查詢操作之前,系統(tǒng)會執(zhí)行你的onLoaderReset()回調(diào)方法。在這個回調(diào)方法中,你應該刪除當前Cursor上的所有數(shù)據(jù),避免發(fā)生內(nèi)存泄露。一旦onLoaderReset()執(zhí)行結束,CursorLoader就會重新執(zhí)行查詢操作。
例如:
/*
* Invoked when the CursorLoader is being reset. For example, this is
* called if the data in the provider changes and the Cursor becomes stale.
*/
@Override
public void onLoaderReset(Loader<Cursor> loader) {
/*
* Clears out the adapter's reference to the Cursor.
* This prevents memory leaks.
*/
mAdapter.changeCursor(null);
}