我对Android 加载器的理解


加载器用过很多次了,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)。

初始化加载器,回调接口实现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









评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值