概述
加载器 Loader
支持在 Activity
或 Fragment
中异步加载数据,具有如下几个特点:
- 可用于每个
Activity
和Fragment
- 支持异步加载数据
- 监控其数据源并在内容变化时传递新结果
- 在某一配置更改后重建
Loader
时,会自动重新连接上一个Loader
的Cursor
,因此它们无需重新查询其数据
API
简介
LoaderManager
与Activity
或Fragment
相关联的的抽象类,用于管理一个或多个Loader
实例。这有助于应用管理与Activity
或Fragment
生命周期相关联的、运行时间较长的操作。用来管理实例初始化,获取,重启一个Loader
。LoaderManager.LoaderCallbacks
回调接口,用于UI
与LoaderManager
进行交互。执行Loader
回调,绑定分发Loader
,完成加载,重置数据等。Loader
执行异步数据加载的抽象类,基类。运行异步操作,有开始,完成,后台加载等接口实现。常用CursorLoader
或自己定义的子类。AsyncTaskLoader
提供AsyncTask
来执行工作的抽象加载器。CursorLoader
AsyncTaskLoader
的子类,它将查询ContentResolver
并返回一个Cursor
。此类采用标准方式为查询游标实现Loader
协议。它是以AsyncTaskLoader
为基础而构建,在后台线程中执行Cursor
查询,以免阻塞应用的UI
。使用此加载器是从ContentProvider
异步加载数据的最佳方式,而不用通过Fragement
或Activity
的API
来执行托管查询。
使用加载器
LoaderManager
可在 Activity
或 Fragment
内管理一个或多个 Loader
实例;但是每个 Activity
或 Fragment
中只有一个 LoaderManager
。常用接口:
1 | public abstract <D> Loader<D> initLoader(int id, Bundle args, |
启动加载器
通常在 Activity
的 onCreate()
方法或 Fragment
的 onActivityCreated()
方法内初始化 Loader
,如:
1 | // Prepare the loader. Either re-connect with an existing one, |
initLoader()
方法参数解析:
id
用于标识加载器的唯一ID
,此示例中为 0args
在构建时提供给加载器的可选参数,可以保存任何数据,示例中为null
callback
LoaderManager.LoaderCallbacks
的实现,LoaderManager
将调用此实现来报告加载器事件
注意:
initLoader()
方法将返回已创建的Loader
,但不必使用该引用,LoaderManager
将自动管理加载器的生命周期,根据需要启动和停止加载,并维护加载器的状态及其相关内容。
重启加载器
使用 initLoader()
时,将使用含有指定 ID
的现有加载器。如果没有则它会创建一个。但是如果需要舍弃这些旧数据并重新开始,可以重启加载器:
1 | // 重启加载器,ID必须和初始化时相同 |
使用加载器回调
LoaderManager.LoaderCallbacks
是交互的回调接口,都是在主线程中执行,包括以下方法:
1 | public interface LoaderCallbacks<D> { |
onCreateLoader()
针对指定的ID
进行实例化并返回新的Loader
onLoadFinished()
在先前创建的加载器完成加载时调用onLoaderReset()
在先前创建的加载器重置且其数据因此不可用时调用
onCreateLoader
详解
initLoader()
方法检查是否已存在由该 ID
指定的加载器。如果没有它将触发LoaderManager.LoaderCallbacks
方法 onCreateLoader()
。在此方法中,返回新建的加载器。比如:返回 CursorLoader
对 ContentProvider
执行查询时所需的一系列完整信息,查询是异步执行的。
onLoadFinished
详解
当先前创建的加载器完成加载时调用此方法。
一般情况下会使用 CursorLoader
和 CursorAdapter
组合的方式异步更新数据源。其中 CursorLoader
异步加载 Cursor
后,通过 CursorAdapter
的 swapCursor()
方法来更新数据,该方法会返回之前旧的 Cursor
,但是我们不需要手动去关闭这个旧游标,CursorLoader
会在 onLoadFinished
执行完后自动关闭这个旧游标。示例及源码分析:
1 | // 1. 示例 |
onLoaderReset
详解
此方法将在先前创建的加载器重置且其数据因此不可用时调用。通过此回调可以了解何时将释放数据,因而能够及时移除其引用。使用 null
来实现:mAdapter.swapCursor(null);
常用 Loader
类定义:public class Loader<D> {...}
CursorLoader
类定义及构造函数
1 | // 类定义 |
AsyncTaskLoader
public abstract class AsyncTaskLoader<D> extends Loader<D> {...}
自定义 Loader
问题: ????数据是需要两次 cursor 拼接才能完成,该如何实现?