• SimpleCursorAdapter与startManagingCursor

    查询数据方法解析
    服务器君一共花费 20.964 ms 进行了 4 次数据库查询,努力地为您提供了这个页面。
    广告很萌的
    1. Chapter: Android SQLite增删查改实例(数据:魔弹之王)
      1. 1. Android SQLite增删查改实例代码部分
      2. 2. SimpleCursorAdapter与startManagingCursor

    在前面例子 Android SQLite增删查改实例代码部分 中,我们看一下 TestDBActivity 的 queryTheCursor 方法。

    public void queryTheCursor(View view) {
    	Cursor c = mgr.queryTheCursor();
    	startManagingCursor(c); //托付给activity根据自己的生命周期去管理Cursor的生命周期
    	CursorWrapper cursorWrapper = new CursorWrapper(c) {
    		@Override
    		public String getString(int columnIndex) {
    			//将简介前加上年龄
    			if (getColumnName(columnIndex).equals("info")) {
    				int age = getInt(getColumnIndex("age"));
    				return age + " years old, " + super.getString(columnIndex);
    			}
    			return super.getString(columnIndex);
    		}
    	};
    	//确保查询结果中有"_id"列
    	SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_2,
    			cursorWrapper, new String[]{"name", "info"}, new int[]{android.R.id.text1, android.R.id.text2});
    	ListView listView = (ListView) findViewById(R.id.listView_db);
    	listView.setAdapter(adapter);
    }
    

    SimpleCursorAdapter

    一般在做网页的时候,要显示一个列表的数据,一般是对一个list的类进行循环,输出一大串的HTML字符串。数据比较多的话就会分页,比如一页10条记录,去数据库查询的时候就会limit 10条记录,速度非常快。

    但在 Android中遇到几千条数据的时候,上下滑动,跟几十条数据的滑动流畅程度差不多,就是刚开始载入速度不一样。对Android 中的Adapter 数据绑定,进行Log输出后,发现是边滑动,数据边绑定的,并不是有多少数据一次性绑定完。但是数据一般是用sql 语句一次性查询出来,这点跟Web中的还是有点区别。

    Android中ListView一般跟Cursor和Adapter有关。很多东西google都帮你弄好了,你只需要按照它约定的弄就行了。“你动不了Application Framework 的大结构,也不需要动。这是福利不是约束”

    SimpleCursorAdapter 的函数定义是:

    SimpleCursorAdapter(Context context, int layout, Cursor c, String[] from, int[] to)
    

    第二个layout的参数是ListView中单行的布局, c是你数据的游标。刚开始其实from和to比较让人不熟悉,From是你查询出的数据,to是单行布局中的单独控件,一对一的关系,用起来非常方便。比如:

    SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
    	R.layout.provice_list_item, cursor,
    	new String[] {Location.PROVICE, Location.CITY },
    	new int[] { R.id.princeTextView,android.R.id.text1 });
    

    写好Adapter,基本上大部分工作已经完成,只需要给你的listview设置这个adapter就行了。一个显示数据的列表就完成了。

    需要注意的是SimpleCursorAdapter的应用,当我们使用这个适配器时,我们必须先得到一个Cursor对象,这里面有几个问题:如何管理Cursor的生命周期,如果包装Cursor,Cursor结果集都需要注意什么。

    如果手动去管理Cursor的话会非常的麻烦,还有一定的风险,处理不当的话运行期间就会出现异常,幸好Activity为我们提供了startManagingCursor(Cursor cursor)方法,它会根据Activity的生命周期去管理当前的Cursor对象。

    startManagingCursor

    下面是 startManagingCursor 方法的说明:

    /** 
     * This method allows the activity to take care of managing the given 
     * {@link Cursor}'s lifecycle for you based on the activity's lifecycle. 
     * That is, when the activity is stopped it will automatically call 
     * {@link Cursor#deactivate} on the given Cursor, and when it is later restarted 
     * it will call {@link Cursor#requery} for you.  When the activity is 
     * destroyed, all managed Cursors will be closed automatically. 
     *  
     * @param c The Cursor to be managed. 
     *  
     * @see #managedQuery(android.net.Uri , String[], String, String[], String) 
     * @see #stopManagingCursor 
     */  
    

    文中提到,startManagingCursor方法会根据Activity的生命周期去管理当前的Cursor对象的生命周期,就是说当Activity停止时他会自动调用Cursor的deactivate方法,禁用游标,当Activity重新回到屏幕时它会调用Cursor的requery方法再次查询,当Activity摧毁时,被管理的Cursor都会自动关闭释放。

    如何包装Cursor?我们会使用到CursorWrapper对象去包装我们的Cursor对象,实现我们需要的数据转换工作,这个CursorWrapper实际上是实现了Cursor接口。我们查询获取到的Cursor其实是Cursor的引用,而系统实际返回给我们的必然是Cursor接口的一个实现类的对象实例,我们用CursorWrapper包装这个实例,然后再使用SimpleCursorAdapter将结果显示到列表上。

    Cursor结果集需要注意些什么:一个最需要注意的是,在我们的结果集中必须要包含一个“_id”的列,否则SimpleCursorAdapter就会翻脸不认人,为什么一定要这样呢?因为这源于SQLite的规范,主键以“_id”为标准。

    解决办法有三:

    • 第一,建表时根据规范去做;
    • 第二,查询时用别名,例如:SELECT id AS _id FROM person;
    • 第三,在CursorWrapper里做文章:
    CursorWrapper cursorWrapper = new CursorWrapper(c) {  
        @Override  
        public int getColumnIndexOrThrow(String columnName) throws IllegalArgumentException {  
            if (columnName.equals("_id")) {  
                return super.getColumnIndex("id");  
            }  
            return super.getColumnIndexOrThrow(columnName);  
        }  
    };  
    

    如果试图从CursorWrapper里获取“_id”对应的列索引,我们就返回查询结果里“id”对应的列索引即可。

更多 推荐条目

Welcome to NowaMagic Academy!

现代魔法 推荐于 2013-02-27 10:23   

本章最新发布
随机专题
  1. [软件工程与项目管理] 开始使用Git 3 个条目
  2. [软件工程与项目管理] 浏览器的HTML解析器 8 个条目
  3. [计算机算法] 两数交换的各种算法细节 2 个条目
  4. [移动开发] 从代码角度去认识 Handler 4 个条目
  5. [软件工程与项目管理] 了解一点WebKit 9 个条目
  6. [JavaScript程序设计] 关于HTTP Keep-Alive 6 个条目
  7. [JavaScript程序设计] Web实时通信技术名词解析 5 个条目
  8. [移动开发] Android抽屉导航NavigationDrawer 5 个条目
  9. [PHP程序设计] PHP扩展模块安装 1 个条目
  10. [JavaScript程序设计] jQuery与表单操作 2 个条目
  11. [Python程序设计] Tornado表单处理 3 个条目
  12. [C语言程序设计] 结构体基本知识 1 个条目
窗口 -- [资讯]