【转载】Android 装载器---使用LoaderManager的回调方法
LoaderManager.LoaderCallbacks是一个让客户与LoadManager进行交互的回调接口。
装载器,尤其是CursorLoader装载器,被期望用来保存被终止后的数据,这样就允许应用程序在Activity之间或Fragment的onStop()和onStart()方法之间进行切换时保存数据,以便在用户返回应用程序时,它们不需要因数据重载而等待。使用LoaderManager.LoaderCallbacks()的回调方法就知道在什么时候要创建一个新的装载器,并且告诉应用程序什么时候是终止使用装载器数据的时间。
LoaderManager.LoaderCallbacks接口包含以下方法:
1. onCreateLoader()---用给定的ID实例化并返回一个新的Loader对象;
2. onLoaderFinished()---当之前创建的装载器已经完成它的装载时,调用这个方法;
3. onLoaderReset()---当之前创建的装载器被重置时,调用这个方法,这样会使这个装载器的数据变的无效。
下面分别对这些方法进行详细说明。
onCreateLoader
当你想要访问一个装载器是时(例如,通过initLoader()方法),它会检查指定ID的装载器是否存在,如果不存在,它会触发LoaderManager.LoaderCallbacks的onCreateLoader()回调方法。这是创建一个新的装载器的地方,典型的是创建一个CursorLoader装载器,但是你能够实现你自己的Loader类的子类。
例如:
// If non-null, this is the current filter the user has provided. String mCurFilter; ... public Loader<Cursor> onCreateLoader(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"); }
在这个列子中,onCreateLoader()回调方法创建了一个CursorLoader装载器,你必须使用构造器方法来创建这个CursorLoader对象,它需要一整套执行对ContentProvider的查询所需要信息,具体需要如下:
1. uri---要获取的内容的位置(URI);
2. projection---一个要返回的列的列表,如果传递null,将返回所有的列,这样是低效的。
3. selection---一个要返回的行的过滤器声明,它使用SQL WHERE子句的格式(不包括WHERE关键字本身)。传递null时将返回给定URI的所有行数据。
4. selectionArgs---你可以在selection中包含“?”字符,这些字符将会被selectionArgs中的值顺序替换。这些值将作为字符串被绑定。
5. sortOrder---使用SQL ORDER BY子句的格式(不包括ORDER BY自己)指定行记录是如何排序的,如果传递null将会使用默认的排序,也可以是无序的。
onLoadFinished
当之前创建的装载器已经完成了它的加载时这个方法会被调用。在提供给这个装载器的最后的数据释放之前会保证调用这个方法。在这个时点你应该删除所有的对旧数据使用(因为数据即将被释放),但是你不应该自己做数据的释放,因为装载器本身会做这件事情。
装载器一旦知道应用程序不在使用它,就会释放数据。例如,如果数据是来自CursorLoader对象的一个游标,你不应该自己来调用close()方法,如果游标被放到了CursorAdapter中,你应该使用swapCursor()方法,以便旧的Cursor对象不被关闭。如:
// This is the Adapter being used to display the list's data. SimpleCursorAdapter mAdapter; ... public void onLoadFinished(Loader<Cursor> loader, Cursor data) { // Swap the new cursor in. (The framework will take care of closing the // old cursor once we return.) mAdapter.swapCursor(data); }
onLoaderReset
当之前被创建的装载器被重置的时候,这个方法会被调用。这样就是它的数据变的无效。这个回调能够让你找到数据被释放的时机,以便你能够在数据被释放之前删除对它的引用。
用带有null参数的swapCursor()方法实现这样的调用,如:
// This is the Adapter being used to display the list's data. SimpleCursorAdapter mAdapter; ... public void onLoaderReset(Loader<Cursor> loader) { // 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); }