Android Loader(加载器)详解
Loader(加载器)简介
(1)可用于每个 Activity 和 Fragment。
(3)监控其数据源并在内容变化时传递新结果。
(4)在某一配置更改后重建加载器时,会自动重新连接上一个加载器的 Cursor。 因此,它们无需重新查询其数据。
Loader API Summary(摘要)
Use the loader in the application(在应用中使用加载器)
(1)Activity 或 Fragment。
1.Boot loader(启动加载器)
通常,您会使用 Activity 的 onCreate() 方法或Fragment的 onActivityCreated() 方法初始化 Loader。您执行操作如下:
// Prepare the loader. Either re-connect with an existing one,
// or start a new one.
getLoaderManager().initLoader(0, null, this);
initLoader(int id, Bundle args, LoaderManager.LoaderCallbacks<D> callback)方法采用以下参数:
(1)用于标识加载器的唯一 ID。在此示例中,ID 为 0。
(2)在构建时提供给加载器的可选参数(在此示例中为 null )。
(3)LoaderManager.LoaderCallbacks 实现, LoaderManager 将调用此实现来报告加载器事件。在此示例中,本地类实现 LoaderManager.LoaderCallbacks 接口,因此它会将引用 this 传递给自己。
(1)如果 ID 指定的加载器已存在,则将重复使用上次创建的加载器。
(2)如果 ID 指定的加载器不存在,则 initLoader() 将触发 LoaderManager.LoaderCallbacks 方法 onCreateLoader()。在此方法中,您可以实现代码以实例化并返回新加载器。有关详细介绍,请参阅 onCreateLoader 部分。
2.Restart loader(重启加载器)
要放弃旧数据,请使用 restartLoader()。例如,当用户的查询更改时,此 SearchView.OnQueryTextListener 实现将重启加载器。 加载器需要重启,以便它能够使用修订后的搜索筛选器执行新查询:
public boolean onQueryTextChanged(String newText) {// Called when 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;
}
3.Use LoaderManager callback(使用 LoaderManager 回调)
LoaderManager.LoaderCallbacks 是一个支持客户端与 LoaderManager 交互的回调接口。
加载器(特别是 CursorLoader)在停止运行后,仍需保留其数据。这样,应用即可保留 Activity 或Fragment的 onStop() 和onStart() 方法中的数据。当用户返回应用时,无需等待它重新加载这些数据。您可使用 LoaderManager.LoaderCallbacks 方法了解何时创建新加载器,并告知应用何时停止使用加载器的数据。
(1)onCreateLoader():针对指定的 ID 进行实例化并返回新的 Loader
(2)onLoadFinished() :将在先前创建的加载器完成加载时调用
(3)onLoaderReset(): 将在先前创建的加载器重置且其数据因此不可用时调用
当您尝试访问加载器时(例如,通过 initLoader()),该方法将检查是否已存在由该 ID 指定的加载器。如果没有,它将触发 LoaderManager.LoaderCallbacks 方法 onCreateLoader()。在此方法中,您可以创建新加载器。 通常,这将是 CursorLoader,但您也可以实现自己的 Loader 子类。
在此示例中,onCreateLoader() 回调方法创建了 CursorLoader。您必须使用其构造函数方法来构建 CursorLoader。该方法需要对 ContentProvider 执行查询时所需的一系列完整信息。具体地说,它需要:
2)projection:要返回的列的列表。传递 null 时,将返回所有列,这样会导致效率低下
3)selection:一种用于声明要返回哪些行的过滤器,其格式为 SQL WHERE 子句(WHERE 本身除外)。传递 null 时,将为指定的 URI 返回所有行
4)selectionArgs:您可以在 selection 中包含 ?s,它将按照在 selection 中显示的顺序替换为 selectionArgs 中的值。该值将绑定为字串符
5)sortOrder:行的排序依据,其格式为 SQL ORDER BY 子句(ORDER BY 自身除外)。传递 null 时,将使用默认排序顺序(可能并未排序)
// 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");
}
(2)onLoadFinished
当先前创建的加载器完成加载时,将调用此方法。该方法必须在为此加载器提供的最后一个数据释放之前调用。 此时,您应移除所有使用的旧数据(因为它们很快会被释放),但不要自行释放这些数据,因为这些数据归其加载器所有,其加载器会处理它们。
// 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);
}
(3)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);
}
Example(示例)
以下是一个 Fragment 完整实现示例。它展示了一个 ListView,其中包含针对联系人内容提供程序的查询结果。它使用 CursorLoader 管理提供程序的查询。
应用如需访问用户联系人(正如此示例中所示),其清单文件必须包括权限 READ_CONTACTS。
public static class CursorLoaderListFragment extends ListFragmentimplements OnQueryTextListener, LoaderManager.LoaderCallbacks<Cursor> {// This is the Adapter being used to display the list's data.SimpleCursorAdapter mAdapter;// If non-null, this is the current filter the user has provided.String mCurFilter;@Override public void onActivityCreated(Bundle savedInstanceState) {super.onActivityCreated(savedInstanceState);// Give some text to display if there is no data. In a real// application this would come from a resource.setEmptyText("No phone numbers");// We have a menu item to show in action bar.setHasOptionsMenu(true);// Create an empty adapter we will use to display the loaded data.mAdapter = new SimpleCursorAdapter(getActivity(),android.R.layout.simple_list_item_2, null,new String[] { Contacts.DISPLAY_NAME, Contacts.CONTACT_STATUS },new int[] { android.R.id.text1, android.R.id.text2 }, 0);setListAdapter(mAdapter);// Prepare the loader. Either re-connect with an existing one,// or start a new one.getLoaderManager().initLoader(0, null, this);}@Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {// Place an action bar item for searching.MenuItem item = menu.add("Search");item.setIcon(android.R.drawable.ic_menu_search);item.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);SearchView sv = new SearchView(getActivity());sv.setOnQueryTextListener(this);item.setActionView(sv);}public boolean onQueryTextChange(String newText) {// Called when 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;}@Override public boolean onQueryTextSubmit(String query) {// Don't care about this.return true;}@Override public void onListItemClick(ListView l, View v, int position, long id) {// Insert desired behavior here.Log.i("FragmentComplexList", "Item clicked: " + id);}// These are the Contacts rows that we will retrieve.static final String[] CONTACTS_SUMMARY_PROJECTION = new String[] {Contacts._ID,Contacts.DISPLAY_NAME,Contacts.CONTACT_STATUS,Contacts.CONTACT_PRESENCE,Contacts.PHOTO_ID,Contacts.LOOKUP_KEY,};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");}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);}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);}
}
本文是来自于Google Android Developer。
Android Loader(加载器)详解相关推荐
- C 编译器、链接器、加载器详解
原文请见 C 编译器.链接器.加载器详解 0. 预编译 在编译 C++ 程序的预处理阶段,源程序中的所有常量表达式都需要首先计算并替换为对应的具体数值. C语言编译器在对源代码编译之前,还需要进一步的 ...
- JVM--类加载器详解
42. JVM--类加载器详解 ● 类加载器子系统作用: 1. 类加载器子系统负责从文件系统或者网络中加载Class文件,class文件在文件开头有特定的文件标识. 2. ClassLoader只负责 ...
- JVM-类加载器 详解(手画多图)面试常问 绝对值得阅读!!!
受多种情况的影响,又开始看JVM 方面的知识. 1.Java 实在过于内卷,没法不往深了学. 2.面试题问的多,被迫学习. 3.纯粹的好奇. 很喜欢一句话:"八小时内谋生活,八小时外谋发展. ...
- JVM------类加载器详解
JVM------类加载器详解 1.图解类加载器工作流程 2.类加载器种类 3.类加载器的加载顺序 4.一些需要了解的机制 1.图解类加载器工作流程 2.类加载器种类 启动类加载器(Bootstrap ...
- C编译器、链接器、加载器详解
一.概述 C语言的编译链接过程要把我们编写的一个c程序(源代码)转换成可以在硬件上运行的程序(可执行代码),需要进行编译和链接.编译就是把文本形式源代码翻译为机器语言形式的目标文件的过程.链接是把目标 ...
- android 图片横竖判断_Android横竖屏切换及其对应布局加载问题详解
本文为大家分享了Android横竖屏切换及其对应布局加载问题,供大家参考,具体内容如下 第一,横竖屏切换连带横竖屏布局问题: 如果要让软件在横竖屏之间切换,由于横竖屏的高宽会发生转换,有可能会要求不同 ...
- 【胖虎的逆向之路】02——Android整体加壳原理详解实现
[胖虎的逆向之路](02)--Android整体加壳原理详解&实现 Android Apk的加壳原理流程及详解 文章目录 [胖虎的逆向之路](02)--Android整体加壳原理详解& ...
- php自动加载类与路由,PHP实现路由与类自动加载步骤详解
这次给大家带来PHP实现路由与类自动加载步骤详解,PHP实现路由与类自动加载步骤详解的注意事项有哪些,下面就是实战案例,一起来看一下. 项目目录如下 入口文件index.php<?php def ...
- Java类的加载过程详解 面试高频!!!值得收藏!!!
受多种情况的影响,又开始看JVM 方面的知识. 1.Java 实在过于内卷,没法不往深了学. 2.面试题问的多,被迫学习. 3.纯粹的好奇. 很喜欢一句话: 八小时内谋生活,八小时外谋发展. 望别日与 ...
- 中yeti不能加载_第二十章_类的加载过程详解
类的加载过程详解 概述 在 Java 中数据类型分为基本数据类型和引用数据类型.基本数据类型由虚拟机预先定义,引用数据类型则需要进行类的加载 按照 Java 虚拟机规范,从 Class 文件到加载到内 ...
最新文章
- java log4j mysql_java – log4j:MySQL的JDBCAppender错误
- TypeError: 'module' object is not callable 原因分析
- angular 指令渲染_Angular JS指令有后期渲染回调吗?
- 【Java】5.3 成员变量和局部变量
- P1064 金明的预算方案(分组背包)
- ArcGIS License启动无响应
- c语言小数加分,求救:c语言课程设计 员工工资管理程序 有加分的。谢谢
- encipher.min.php,陌屿授权系统(5.7)最新版 网站授权 - 下载 - 搜珍网
- 【渝粤教育】国家开放大学2019年春季 0736-22T烹饪工艺学(2) 参考试题
- 警告warningC4018有符号/无符号不匹配
- [vue] watch和计算属性有什么区别?
- ServletResponse的getOutputStream()与getWriter()使用冲突
- Sublime Text 使用记录汇总
- CentOS中文乱码问题
- 1.84亿月活换来400亿港元估值,网易云音乐的钱途在哪儿?
- Oracle批量导出Hive建表语句
- 在香港用什么软件可以唱歌?香港K歌app推荐
- Mac —— QuickTime录屏 声音小解决
- 怎么彻底删除users下的文件夹_users中的那些文件可以删除。。。。。。。有哪些文件是不能删除呢?...
- 用crontab每隔1分钟执行一个命令行脚本