android适配器SimpleCursorAdapter的使用以及最后一个参数的作用
来源:互联网 发布:苹果8手机怎么打开网络 编辑:程序博客网 时间:2024/06/02 01:08
在android开发中,我们经常用SimpleCursorAdapter来绑定数据库里面的数据,很多人在使用这个类的时候并不知道具体怎么样来用,或者说还有很多疑问,比如最后一个参数该怎么写,这个cursor什么时候关闭,是怎么管理cursor的等等。
在android的不同的版本中,对SimpleCursorAdapter的使用方法是不同的,我们先来看下SimpleCursorAdapter构造方法,SimpleCursorAdapter有两个构造方法,其实可以归并为一个构造方法,我们看下构造方法的说明:
我们看最后一个参数flags,它有两个值可以选择分别为:CursorAdapter.FLAG_AUTO_REQUERY
和CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER
,另外一个构造方法就是少了最后一个参数,默认被设置为CursorAdapter.FLAG_AUTO_REQUERY
。
首先我们来看没有flag参数或者参数为CursorAdapter.FLAG_AUTO_REQUERY
的情况,这种是在android3.0以下版本中才使用的,在分为android3.0及以上的版本中,已经被废弃了,是不建议使用的,我们还是来说明下使用方法
final Cursor c = managedQuery(Persons.CONTENT_URI, null, null, null, null); SimpleCursorAdapter simpleCursorAdapter = new SimpleCursorAdapter( this, R.layout.list_item, c, new String[] {Persons.NAME, Persons.AGE}, new int[] {R.id.textViewName, R.id.textViewAge} ); ListView listView = (ListView)findViewById(R.id.listView); listView.setAdapter(simpleCursorAdapter);
正如字面意思,FLAG_AUTO_REQUERY会自动查询如果数据库中的数据发生了变化以实时反映到界面上来,这样使用有一个问题,查询数据是发生在UI线程中,会造成卡顿的现象,甚至出现ANR异常,取决于手机的配置及数据的大小,这也是android3.0及以上放弃的原因,尽管如此,我们还是有些问题需要来理解。
一般来说我们使用Cursor需要close,但是在这里我们并没close,那么是怎么处理的呢,原理是Activity自己帮我处理的,大家看我是使用managedQuery来获取Cursor对象的,在这个方法中
@Deprecatedpublic final Cursor managedQuery(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { Cursor c = getContentResolver().query(uri, projection, selection, selectionArgs, sortOrder); if (c != null) { startManagingCursor(c); } return c;}
用getContentResolver().query()获取到Cursor对象以后,使用startManagingCursor()把Cursor对象加入到Activity中管理。我们看下startManagingCursor方法
@Deprecated public void startManagingCursor(Cursor c) { synchronized (mManagedCursors) { mManagedCursors.add(new ManagedCursor(c)); } }
以Cursor构建了一个ManagedCursor对象,并加入到一个类型为ArrayList的mManagedCursors容器里面去了,在Activity中的onDestroy()方法中,我们看到下面的代码
// close any cursors we are managing. synchronized (mManagedCursors) { int numCursors = mManagedCursors.size(); for (int i = 0; i < numCursors; i++) { ManagedCursor c = mManagedCursors.get(i); if (c != null) { c.mCursor.close(); } } mManagedCursors.clear(); }
没错,从mManagedCursors循环取出所有的ManagedCursor对象,并关闭里面的Cursor,在Activity中的performRestart()方法,我们看到如下代码
synchronized (mManagedCursors) { final int N = mManagedCursors.size(); for (int i=0; i<N; i++) { ManagedCursor mc = mManagedCursors.get(i); if (mc.mReleased || mc.mUpdated) { if (!mc.mCursor.requery()) { if (getApplicationInfo().targetSdkVersion >= android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) { throw new IllegalStateException( "trying to requery an already closed cursor " + mc.mCursor); } } mc.mReleased = false; mc.mUpdated = false; } } }
我们看到了mCursor.requery()方法,这个方法是用来重新查询数据,在Activity重新开始的时候,performRestart()方法是Activity重新开始过程会被调用的方法。这下大家明白Activity是怎么管理Cursor的吧!注意如果大家在使用这个的时候一定要managedQuery()方法来获取Cursor,不然Cursor没被Activity管理,会游离在外,有可能会出现游标未关闭异常,大家最好不用这种方法了,android已经废弃!!!
然后我们看使用第二个参数来构建SimpleCursorAdapter对象即Flag为CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER,这是android3.0及以上的做法,我们需要使用到CursorLoader来加载数据了
simpleCursorAdapter = new SimpleCursorAdapter( this, R.layout.list_item, null, new String[] {Persons.NAME, Persons.AGE}, new int[] {R.id.textViewName, R.id.textViewAge}, CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER ); ListView listView = (ListView)findViewById(R.id.listView); listView.setAdapter(simpleCursorAdapter); LoaderManager loaderManager = getLoaderManager(); loaderManager.initLoader(0, null, this);
在回调方法中写上对应的代码
@Override public Loader<Cursor> onCreateLoader(int id, Bundle args) { return new CursorLoader(this, Persons.CONTENT_URI, null, null, null, null); } @Override public void onLoadFinished(Loader<Cursor> loader, Cursor c) { simpleCursorAdapter.swapCursor(c); } @Override public void onLoaderReset(Loader<Cursor> loader) { simpleCursorAdapter.swapCursor(null); }
当数据库的数据变化的时候会自动回调onLoadFinished()来更新界面,同样这个方式也是由Activity来管理Cursor的,simpleCursorAdapter.swapCursor()会把之前的Cursor给close掉,并使用新的Cursor对象,onLoaderReset()就是由Activity中的performDestroy()来间接调用的,simpleCursorAdapter.swapCursor(null);被调用后就关闭了Cursor,这个方式获取Cursor是在子线程中,加载完成后会回调onLoadFinished()方法,不会阻塞UI线程,提高了流畅度,另外当Configuration发生变化是可以重用Cursor,不需要去重新获取Cursor,提高了效率,强烈的推荐大家在今后的开发中,使用这种方式。
好了,SimpleCursorAdapter的使用就说到这里,大家有什么疑问或者建议请给我留言!!!
最后给出一个参考demo https://github.com/takeyuweb/android-CursorLoaderSample 是个日本人写的,大家可以参照着看,我的部分代码也是来自于它
- android适配器SimpleCursorAdapter的使用以及最后一个参数的作用
- Android SimpleCursorAdapter的使用
- Android基础学习之BaseAdaptery以及SimpleCursorAdapter的使用
- Android中SimpleCursorAdapter的使用
- 我的Android进阶之旅------>Android ListView 应用解析(使用ArrayAdapter,SimpleAdapter和SimpleCursorAdapter适配器)
- simpleCursorAdapter的一个问题
- Android开发模板------自定义SimpleCursorAdapter的使用
- android之自定义SimpleCursorAdapter的使用
- android SQlite结合SimpleCursorAdapter的简单使用
- Android适配器之---SimpleCursorAdapter
- Android的SimpleCursorAdapter出错
- SimpleCursorAdapter 的使用
- SimpleCursorAdapter的使用
- SimpleCursorAdapter的使用
- SimpleCursorAdapter的简单使用
- Android的 SimpleAdapter和SimpleCursorAdapter
- SimpleAdapter 和 SimpleCursorAdapter的使用
- SimpleCursorAdapter与ListView的使用
- Android中使用GSON包解析JSON数据(简单JSON)
- 在Ubuntu上为Android系统内置C可执行程序测试Linux内核驱动程序
- 一位毕业生的肺腑之言: 大学生活应该怎样度过——写给学弟学妹
- automake示例
- Nginx源码分析 - 基础数据结构篇 - 数组结构 ngx_array.c
- android适配器SimpleCursorAdapter的使用以及最后一个参数的作用
- C# 异步
- MYSQL存储过程怎么写
- Android中使用GSON包解析JSON数据(复杂JSON)
- 在Cordova中自定义AndroidTest(Instrumented Unit Test)
- Android Camera Framework
- 几种任务调度的 Java 实现方法与比较
- Android中使用Volley开源库进行Http网络请求(GET方式)
- 取消word的修订模式