Android的CursorLoader用法小结
工作内容集中到Contact模块,这个应用查询数据的地方很多,其使用了CursorLoader这个工具大大简化了代码复杂度。Android自3.0提供了Loader机制,当时google的API只是简单的介绍了一下没有给出用法,大家很少有关注。后来因为重度模型下的性能优化,R&D的朋友发现这个东西非常给力,这才开始注意到这个强大的工具。CursorLoader是Loader的子类,可以说是Loader的升级版。这篇小结以loader为基础说明,弄懂原理之后也就明白了CursorLoader。
先说说google官方对Loader的介绍Loader对activity和fragment可用;Loader可以移步加载数据;loader自己会监视数据源的变化并且会主动上报;当发生配置上的变化,重新生成的loader会自动连接到变化前的cursor,这样就避免再查一次数据库。咱自己在补充一个,loader能在应用不使用查询到的资源时候,自动将其释放。这些介绍自android3.0之后,就可以从官方文档山看到。当时依据这些并不知道怎么样使用,看了framework侧的实现之后还是一头雾水:咋用。现在来看这就像activity一样,我们可以不知道framework中怎么样开始一个activity怎么样管理activity但是我们仍然能很好的使用activity;对于CursorLoader,我们大可以不必知道framework中的原理,只要利用好google提供的接口LoaderManager以及为其注册事件的接口LoaderManager.LoaderCallbacks就可以实现我们需要的功能。
实际上CursorLoader完全可以看成一个很牛的查询工具,拥有一般的查询不具备的能力,如上面的google官方介绍。我们通过LoaderManager.LoaderCallbacks接口来在适当的时候提供查询配置或者利用查询返回到的结果。使用好CursorLoader重在实现好LoaderManager.LoaderCallbacks接口。看下这个接口里面提供了哪些方法:
public interface LoaderCallbacks<D> {
public Loader<D> onCreateLoader(int id, Bundle args);
public void onLoadFinished(Loader<D> loader, D data);
public void onLoaderReset(Loader<D> loader);
}
第一个方法onCreateLoader是创建Loader时候调用,是为了提供查询的配置,比如查询地址,查询项目等。这个方法会在loader初始化也就是注册这个接口的时候调用,常见代码如下:
getLoaderManager().initLoader(0, null, this);
第一个参数是当前activity里面loader的ID,一般为0,第二个参数一般置null,第三个就是实现了LoaderManager.LoaderCallbacks的类,一般就是当前activity。这句代码执行之后就会执行onCreateLoader,然后去查询,查询结束之后就会执行onLoadFinished,做你需要做的事情。一般就在第二个方法里面利用查询结果,如传递到一个adapter进行显示。第三个方法onLoaderReset是在我们的配置发生变化的,使用restartLoader(int , Bundle ,LoaderManager.LoaderCallbacks<D>)方法重新初始化loader之后调用的,一般是用来释放对前面loader查询到的结果引用。对Loader的使用只需要在重新初始化之前去除引用,退出activity时候不需要关闭cursor释放资源。
到这里loader的用法就已经说完了,记住上面三个方法的用处,在适当的地方初始化loader,我们就可以利用Loader实现我们的需要。现在说说Loader和CursorLoader的关系:Loader是核心,其已经实现了基本功能;AsyncTaskLoader继承自Loader,主要任务就是将耗时操作从主线程中剥离出来;CursorLoader继承自AsyncTaskLoader,是泛型类的一个具体类,也是我们最常用Loader。
Loader的到来给android应用开发带来了很大的方便。在数据加载的性能优化中有一项分布加载,没有Loader之前,我们需要将查询实现在AsyncQueryHandler类里面,在其onQueryComplete回调方法里面触发后续查询。上面这些需要自定义一个内部类,一堆代码,搞得晕乎乎的。%>_<% 用来Loader只要在onLoadFinished里面增加一些判断即可,很方便。
public class ListViewLoader extends ListActivity
implements LoaderManager.LoaderCallbacks<Cursor> { // This is the Adapter being used to display the list's data
SimpleCursorAdapter mAdapter; // These are the Contacts rows that we will retrieve
static final String[] PROJECTION = new String[] {ContactsContract.Data._ID,
ContactsContract.Data.DISPLAY_NAME}; // This is the select criteria
static final String SELECTION = "((" +
ContactsContract.Data.DISPLAY_NAME + " NOTNULL) AND (" +
ContactsContract.Data.DISPLAY_NAME + " != '' ))"; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); // Create a progress bar to display while the list loads
ProgressBar progressBar = new ProgressBar(this);
progressBar.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT, Gravity.CENTER));
progressBar.setIndeterminate(true);
getListView().setEmptyView(progressBar); // Must add the progress bar to the root of the layout
ViewGroup root = (ViewGroup) findViewById(android.R.id.content);
root.addView(progressBar); // For the cursor adapter, specify which columns go into which views
String[] fromColumns = {ContactsContract.Data.DISPLAY_NAME};
int[] toViews = {android.R.id.text1}; // The TextView in simple_list_item_1 // Create an empty adapter we will use to display the loaded data.
// We pass null for the cursor, then update it in onLoadFinished()
mAdapter = new SimpleCursorAdapter(this,
android.R.layout.simple_list_item_1, null,
fromColumns, toViews, );
setListAdapter(mAdapter); // Prepare the loader. Either re-connect with an existing one,
// or start a new one.
getLoaderManager().initLoader(, null, this);
} // Called when a new Loader needs to be created
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
// Now create and return a CursorLoader that will take care of
// creating a Cursor for the data being displayed.
return new CursorLoader(this, ContactsContract.Data.CONTENT_URI,
PROJECTION, SELECTION, null, null);
} // Called when a previously created loader has finished loading
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);
} // Called when a previously created loader is reset, making the data unavailable
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);
} @Override
public void onListItemClick(ListView l, View v, int position, long id) {
// Do something when a list item is clicked
}
}
Android的CursorLoader用法小结的更多相关文章
- Android LoaderManager与CursorLoader用法
一.基本概念 1.LoaderManager LoaderManager用来负责管理与Activity或者Fragment联系起来的一个或多个Loaders对象. 每个Activity或者Fragme ...
- 十、Android学习第九天——小结(转)
(转自:http://wenku.baidu.com/view/af39b3164431b90d6c85c72f.html) 十.Android学习第九天——小结 通过这段时间的学习,今晚上来做个小小 ...
- C++ typedef用法小结 (※不能不看※)
C++ typedef用法小结 (※不能不看※) 第一.四个用途 用途一: 定义一种类型的别名,而不只是简单的宏替换.可以用作同时声明指针型的多个对象.比如:char* pa, pb; // 这多数不 ...
- MVC图片上传详解 IIS (安装SSL证书后) 实现 HTTP 自动跳转到 HTTPS C#中Enum用法小结 表达式目录树 “村长”教你测试用例 引用provinces.js的三级联动
MVC图片上传详解 MVC图片上传--控制器方法 新建一个控制器命名为File,定义一个Img方法 [HttpPost]public ActionResult Img(HttpPostedFile ...
- Android AIDL的用法
一.什么是AIDL服务 一般创建的服务并不能被其他的应用程序访问.为了使其他的应用程序也可以访问本应用程序提供的服务,Android系统采用了远程过程调用(Remote Procedure Cal ...
- 转载:Hadoop排序工具用法小结
本文转载自Silhouette的文章,原文地址:http://www.dreamingfish123.info/?p=1102 Hadoop排序工具用法小结 发表于 2014 年 8 月 25 日 由 ...
- 【Android学习】android:layout_weight的用法实例
对于android:layout_weight的用法,用下面的例子来说明: <LinearLayout xmlns:android="http://schemas.android.co ...
- [No000010]Ruby 中一些百分号(%)的用法小结
#Ruby 中一些百分号(%)的用法小结 #这篇文章主要介绍了Ruby 中一些百分号(%)的用法小结,需要的朋友可以参考下 what_frank_said = "Hello!"#% ...
- 函数fgets和fputs、fread和fwrite、fscanf和fprintf用法小结 (转)
函数fgets和fputs.fread和fwrite.fscanf和fprintf用法小结 字符串读写函数fgets和fputs 一.读字符串函数fgets函数的功能是从指定的文件中读一个字符串到字符 ...
随机推荐
- Q郵箱轉移自定義目錄中的郵件
1.之前在Q郵箱上建立了許多規則和收件箱,現在想統一用Mac上的郵局管理 2.Mac上會同步對應郵箱的自定義目錄,此時這些目錄便十分多餘礙眼 3.Q郵箱單頁顯示郵件數量上限是100,這意味著手動轉移十 ...
- 一个textview实现文字在图片上面的效果
类似于这样的,其实很简单,可是以前用的是imageview+textview.布局实现多写了好多代码.又不能在图片加文字,显得没技术含量. xml代码如下: <TextView android: ...
- 关于ZF2中一点感悟,service_manager
在zf2中,在serviceLoctor中自定义的内容,可以通$serviceLocator->get('config')['key'],如果是在serivce_manger中定义的服务名,其实 ...
- Linux目录规范和含义(转)
Linux目录配置 在了解了每个文件的相关种类与属性,以及了解了如何更改文件属性/权限的相关信息后,再来要了解的就是, 为什么每套Linux distributions他们的配置文件啊.执行文件啊 ...
- rsyslog日志服务的配置文件分析
基于rsyslog日志服务的日志 在不同的LINUX系统,实现的软件略有不同. syslog,rsyslog,syslog-ng,用于实现系统日志的管理. [root@asianux4 ~]# rpm ...
- Unix 入门
说明:转自以为大神的笔记. 首先,我们一起看看UNIX的目录,因为清楚了目录,才能对UNIX的框架有个大概的印象!当然这里讲的是系统正常运转所必须的,并且一定不能删除或者修改. / 是系统的根目录: ...
- 单例模式-ios
#import <Foundation/Foundation.h> @interface UserContext : NSObject <NSCopying> @propert ...
- DbContextConfiguration 属性
属性 AutoDetectChangesEnabled 获取或设置一个值,该值指示是否通过 DbContext 和相关类的方法自动调用 DetectChanges 方法. 默认值为 true. Ens ...
- Cg Programming/Vertex Transformations
https://en.wikibooks.org/wiki/Cg_Programming/Vertex_Transformations
- AngularJS 的安全Apply
$scope.safeApply = function(fn) { var phase = this.$root.$$phase; if (phase == ‘$apply‘ || p ...