在应用程序中使用CursorLoader所需的元素
Activity
or Fragment
.(一个Acttivity或者Fragment)LoaderManager
.(LoaderManager的实例)CursorLoader
to load data backed by a ContentProvider
. Alternatively, you can implement your own subclass of Loader
or AsyncTaskLoader
to load data from some other source.LoaderManager.LoaderCallbacks
. This is where you create new loaders and manage your references to existing loaders.(实现LoaderManager.LoaderCallbacks,点击这里查看接口详解)SimpleCursorAdapter
.ContentProvider
, when using a CursorLoader
.(数据源,例如ContentProvider)实例化一个Loader:
1 getLoaderManager().initLoader(0, null, this);
第一个参数:用来区分loader实例的唯一ID
第二个参数:可选参数
第三个参数:一个实现了LoaderManager.LoaderCallbacks接口的实例
LoaderManager.LoaderCallbacks包含三个方法:
onCreateLoader() 初始化并且返回一个给定ID的Loader
onLoadFinished() 在之前创建的loader完成之后调用
onLoaderReset() 在之前创建的loader reset时调用
onCreateLoader(int id,Bundle args)
在下面这个例子中,我们用到了CursorLoader,在构造函数中有以下参数:
null
will return all columns, which is inefficient.null
will return all rows for the given URI.null
will use the default sort order, which may be unordered.// If non-null, this is the current filter the user has provided. String mCurFilter; ... public LoaderonCreateLoader(int id, Bundle args) { // This is called when a new Loader needs to be created. This // sample only has one Loader, so we don't care about the ID. // First, pick the base URI to use depending on whether we are // currently filtering. Uri baseUri; if (mCurFilter != null) { baseUri = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI, Uri.encode(mCurFilter)); } else { baseUri = Contacts.CONTENT_URI; } // Now create and return a CursorLoader that will take care of // creating a Cursor for the data being displayed. 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"); }
onLoadFinish(Loader
这个方法会确保在释放此loader提供的最后的数据之前调用(原文:This method is guaranteed to be called prior to the release of the last data that was supplied for this loader.)
loader会自动释放应用不再使用到的data,例如,如果这个data是一个来自CursorLoader的cursor,不应该使用close()来释放它,如果这个cursor被放到了一个CursorAdapter,应该使用swapCursor方法来确保旧的Cursor不会被关闭,例如:
// This is the Adapter being used to display the list's data. SimpleCursorAdapter mAdapter; ... public void onLoadFinished(Loaderloader, Cursor data) { // Swap the new cursor in. (The framework will take care of closing the // old cursor once we return.) mAdapter.swapCursor(data); }
onLoaderReset(Loader
这个方法在已创建的loader reset的时候调用,会使得loader的数据不可用
下面的实现调用swapCursor(null):
// This is the Adapter being used to display the list's data. SimpleCursorAdapter mAdapter; ... public void onLoaderReset(Loaderloader) { // This is called when the last Cursor provided to onLoadFinished() // above is about to be closed. We need to make sure we are no // longer using it. mAdapter.swapCursor(null); }
下面是一个完整的例子,它使用一个Fragment读取联系人,必须在manifest文件中添加READ_CONTACTS权限