我对Android 加载器的理解

来源:互联网 发布:紫砂壶品牌 知乎 编辑:程序博客网 时间:2024/04/26 05:53


加载器用过很多次了,SimpleCursorAdapter也应用了很多次,但是AndroidLoader的概念却一直理不清楚,这到底适合什么适合使用更是搞不清楚,优点是什么也没有想过,这里回顾一下。


Android加载器是从 android3.0 引入的概念。支持在Activity或者Fragment中异步加载数据。

官方文档中也详细地说明了它的特征:


  • 可用于每个 Activity 和 Fragment
  • 支持异步加载数据。
  • 监控其数据源并在内容变化时传递新结果。
  • 在某一配置更改后重建加载器时,会自动重新连接上一个加载器的游标。 因此,它们无需重新查询其数据。

如何实现加载器?


                                              ————启动加载器————

LoaderManager 可在 Activity 或 Fragment 内管理一个或多个 Loader 实例。每个 Activity 或片段中只有一个 LoaderManager

通常,您会在 Activity 的 onCreate() 方法 或 片段的onActivityCreated() 方法内初始化 Loader。您执行操作如下:

getLoaderManager().initLoader(0,null,this);

  • 用于标识加载器的唯一 ID。在此示例中,ID 为 0。
  • 在构建时提供给加载器的可选参数(在此示例中为 null)。
  • LoaderManager.LoaderCallbacks 实现, LoaderManager 将调用此实现来报告加载器事件。在此示例中,本地类实现 LoaderManager.LoaderCallbacks 接口,因此它会传递对自身的引用 this

初始化加载器,回调接口实现3个方法

initLoader() 方法将返回已创建的 Loader,但您不必捕获其引用。LoaderManager 将自动管理加载器的生命周期。LoaderManager 将根据需要启动和停止加载,并维护加载器的状态及其相关内容。 这意味着您很少直接与加载器进行交互(有关使用加载器方法调整加载器行为的示例,请参阅LoaderThrottle 示例)。当特定事件发生时,您通常会使用 LoaderManager.LoaderCallbacks 方法干预加载进程。

                                   ————重启加载器————

当您使用 initLoader() 时(如上所述),它将使用含有指定 ID 的现有加载器(如有)。如果没有,则它会创建一个。但有时,您想舍弃这些旧数据并重新开始。

要舍弃旧数据,请使用 restartLoader()。例如,当用户的查询更改时,此 SearchView.OnQueryTextListener 实现将重启加载器。 加载器需要重启,以便它能够使用修订后的搜索过滤器执行新查询:

the action bar search text has changed.  Update    // the search filter, and restart the loader to do a new query    // with this filter.    mCurFilter = !TextUtils.isEmpty(newText) ? newText : null;    getLoaderManager().restartLoader(0, null, this);    return true;}

                             ————使用 LoaderManager 回调————

LoaderManager.LoaderCallbacks 包括以下方法:


onCreateLoader():针对指定的 ID 进行实例化并返回新的 Loader

  • 当您尝试访问加载器时(例如,通过 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");}


  • 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);}

参考:https://developer.android.google.cn/guide/components/loaders.html#app









原创粉丝点击