registerContentObserver()在原始的SQLite光标 [英] registerContentObserver() on raw SQLite Cursor

查看:137
本文介绍了registerContentObserver()在原始的SQLite光标的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所有我见过使用的例子 registerContentObserver()这么做通过的ContentProvider 接口。但是光标有一个 registerContentObserver()电话,所以我想也许在Android人们已经把一些深层次的魔力,将允许获得在 SQLite的更新光标时,从活动结果集的行中的一个改变。无论我做错了,或者有没有这样的魔力。这里的code,我努力着,期望是,当我在按钮上单击以更新的行#1的值,我会得到一个的onChange()回电话。任何想法?

 公共类MainActivity延伸活动{
    私有静态最后弦乐DATABASE_NAME =test.db的;
    公共静态最终字符串变量=dbtest;

    / **第一次创建活动时调用。 * /
    @覆盖
    公共无效的onCreate(包savedInstanceState){
        super.onCreate(savedInstanceState);
        的setContentView(R.layout.main);

        按钮,会使=(按钮)findViewById(R.id.btn_make_record);
        make.setOnClickListener(新OnClickListener(){
            公共无效的onClick(视图v){
                MyOpenHelper哦=新MyOpenHelper(v.getContext());
                SQLiteDatabase WDB = oh.getWritableDatabase();
                ContentValues​​ CV =新ContentValues​​();
                cv.put(价值,将String.valueOf(System.currentTimeMillis的()));
                如果(wdb.insert(MyOpenHelper.TABLE_NAME,空,CV)== -1){
                    Log.d(TAG,无法插入行);
                } 其他 {
                    Log.d(TAG,插入行);
                }
                wdb.close();
            }
        });

        按钮更新=(按钮)findViewById(R.id.btn_update_record);
        update.setOnClickListener(新OnClickListener(){
            公共无效的onClick(视图v){
                MyOpenHelper哦=新MyOpenHelper(v.getContext());
                SQLiteDatabase WDB = oh.getWritableDatabase();
                ContentValues​​ CV =新ContentValues​​();
                cv.put(价值,将String.valueOf(System.currentTimeMillis的()));
                诠释计数= wdb.update(MyOpenHelper.TABLE_NAME,CV,_id =?,新的String [] {1});
                Log.d(TAG,更新+数+行(S));
                wdb.close();
            }
        });

        MyOpenHelper哦=新MyOpenHelper(本);
        SQLiteDatabase RDB = oh.getReadableDatabase();
        光标C = rdb.query(MyOpenHelper.TABLE_NAME,空,_id =?,新的String [] {1},NULL,NULL,NULL);
        startManagingCursor(C);
        contentObserver =新MyContentObserver(新处理器());
        c.registerContentObserver(contentObserver);
    }

    私有类MyContentObserver扩展ContentObserver {
        MyContentObserver(处理程序处理){
            超(处理);
        }

        公共布尔deliverSelfNotifications(){
            返回true;
        }

        公共无效的onChange(布尔selfChange){
            super.onChange(selfChange);
            Log.d(TAG,电锯惊魂行#1的改变);
        }
    }

    MyContentObserver contentObserver;

    公共类MyOpenHelper扩展SQLiteOpenHelper {
        私有静态最终诠释DATABASE_VERSION = 1;
        私有静态最后弦乐TABLE_NAME =测试;
        私有静态最后弦乐TABLE_CREATE =
                CREATE TABLE+ TABLE_NAME +(+
                _id INTEGER PRIMARY KEY AUTOINCREMENT,+
                Value文本);;

        MyOpenHelper(上下文的背景下){
             超(背景下,DATABASE_NAME,空,DATABASE_VERSION);
        }

        @覆盖
        公共无效的onCreate(SQLiteDatabase DB){
            db.execSQL(TABLE_CREATE);
        }

        @覆盖
        公共无效onUpgrade(SQLiteDatabase分贝,INT oldVersion,诠释静态网页){
          // TODO自动生成方法存根
        }
    }
}
 

解决方案

没有考生是吧?好了一个很好的借口,挖掘自己,看着办吧。对于那些谁可能是后我好奇,如果你下载平台源的相关文件看是:

框架/基/核心/爪哇/安卓/数据库/源码/ SQLiteCursor.java 框架/基/核心/爪哇/安卓/数据库/ AbstractCursor.java

它看起来像mContentObservable有信号一个程序的不同部分流失的缓存结果在游标设置,并观察到的是从缓存的结果集,让消费者知道什么时候缓存已经倾倒的信号/更新。它不扎入SQLite的执行触发事件时,底层数据存储进行操作。

不完全是惊人的,但由于我想也许我失去了一些东西。

该文档

All of the examples I've seen of using registerContentObserver() do so through a ContentProvider interface. But Cursor has a registerContentObserver() call, so I figured maybe the Android folks have put together some deep magic that would allow for getting updates on a SQLite cursor when one of the rows from an active result set changed. Either I'm doing it wrong, or there is no such magic. Here's the code I'm working with, the expectation being that when I click on the button to update the value in row #1 I would get an onChange() callback. Any ideas?

public class MainActivity extends Activity {
    private static final String DATABASE_NAME = "test.db";
    public static final String TAG = "dbtest";

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        Button make = (Button)findViewById(R.id.btn_make_record);
        make.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                MyOpenHelper oh = new MyOpenHelper(v.getContext());
                SQLiteDatabase wdb = oh.getWritableDatabase();
                ContentValues cv = new ContentValues();
                cv.put("value", String.valueOf(System.currentTimeMillis()));
                if (wdb.insert(MyOpenHelper.TABLE_NAME, null, cv) == -1) {
                    Log.d(TAG, "Unable to insert row");
                } else {
                    Log.d(TAG, "Inserted row ");
                }
                wdb.close();
            }
        });

        Button update = (Button)findViewById(R.id.btn_update_record);
        update.setOnClickListener(new OnClickListener() {   
            public void onClick(View v) {
                MyOpenHelper oh = new MyOpenHelper(v.getContext());
                SQLiteDatabase wdb = oh.getWritableDatabase();
                ContentValues cv = new ContentValues();
                cv.put("value", String.valueOf(System.currentTimeMillis()));
                int count = wdb.update(MyOpenHelper.TABLE_NAME, cv, "_id = ?", new String[] {"1"});
                Log.d(TAG, "Updated " + count + " row(s)");
                wdb.close();
            }
        });

        MyOpenHelper oh = new MyOpenHelper(this);
        SQLiteDatabase rdb = oh.getReadableDatabase();
        Cursor c = rdb.query(MyOpenHelper.TABLE_NAME, null, "_id = ?", new String[] {"1"}, null, null, null);
        startManagingCursor(c);
        contentObserver = new MyContentObserver(new Handler());
        c.registerContentObserver(contentObserver);
    }

    private class MyContentObserver extends ContentObserver {
        MyContentObserver(Handler handler) {
            super(handler);
        }

        public boolean deliverSelfNotifications() {
            return true;
        }

        public void onChange(boolean selfChange) {
            super.onChange(selfChange);
            Log.d(TAG, "Saw a change in row # 1");
        }
    }

    MyContentObserver contentObserver;

    public class MyOpenHelper extends SQLiteOpenHelper {
        private static final int DATABASE_VERSION = 1;
        private static final String TABLE_NAME = "test";
        private static final String TABLE_CREATE =
                "CREATE TABLE " + TABLE_NAME + " (" +
                "_id INTEGER PRIMARY KEY AUTOINCREMENT," +
                "value TEXT);";

        MyOpenHelper(Context context) {
             super(context, DATABASE_NAME, null, DATABASE_VERSION);
        }

        @Override
        public void onCreate(SQLiteDatabase db) {
            db.execSQL(TABLE_CREATE);
        }

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
          // TODO Auto-generated method stub    
        }
    }
}

解决方案

No takers huh? Well an excellent excuse to dig in myself and figure it out. For those who might be curious after me, if you download the platform source the relevant files to look at are:

frameworks/base/core/java/android/database/sqlite/SQLiteCursor.java frameworks/base/core/java/android/database/AbstractCursor.java

It looks like the mContentObservable is there to signal different parts of a program running off the cached result set in a Cursor, and the observable is a signal from the cached result set to let consumers know when the cache has been dumped/updated. It doesn't tie into the SQLite implementation to fire events when the underlying datastore is manipulated.

Not exactly surprising, but given the docs I thought maybe I was missing something.

这篇关于registerContentObserver()在原始的SQLite光标的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆