博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android ContentObserver
阅读量:6006 次
发布时间:2019-06-20

本文共 4138 字,大约阅读时间需要 13 分钟。

  hot3.png

想象一个场景: 有个TextView, 用来显示数据库一个表的数据总数. 用户通过UI界面对数据进行CRUD的操作. 这个TextView如何实时监控并更新显示数据总数?

目录:

第一节

第二节

第三节

这里比较便捷且高效的方案是使用ContentObserver. 前提是已经建立了ContentProvider的支持. 先分析了一些网上广为流传了一个监控SMS变化的Observer例子. 画个图便于ContentObserver的感性认识.

14181932_D5Tz.png


通过这个图, 主要了解3点就可以:

   1, 建立继承自ContentObserver的对象,实现其onChange()方法.

   2, 在目标Activity中注册和解除.

   3, 在UI线程中, 用Handler接收来自Observer发出的Message, 更新UI.

思路有了, 就看具体的实现了.


一. 首先是建立一个继承自ContentObserver的对象.

public class TAGContentObserver extends ContentObserver{    private Context mContext;    private Handler mHandler;    public static final int TAG_DB_CHANGE = 921;                                                                                                                                                                                              public TAGContentObserver(Context context, Handler handler) {        super(handler);        mContext = context;        mHandler = handler;    }    @Override    public void onChange(boolean selfChange) {        //数据变化, 重新查询最新结果.        Cursor cursor = mContext.getContentResolver().query(TAGDBOpenHelper.CONTENT_URI, null, null, null, null);        //发送Message. 此Handler定义在Activity中, 拆开Message得到结果更新TextView.        mHandler.obtainMessage(TAG_DB_CHANGE, cursor.getCount(), 0).sendToTarget();    }}

重点是实现其onChange()方法, 如注释所写. onChange可以理解为在得到数据变化的通知之后, Observer做的事情. 此例子中是重新查询表的数据总数.


二. 在Activity中注册和解除.

//注册观察者ContentObserver observer = new TAGContentObserver(MainActivity.this, mMyHandler);getContentResolver().registerContentObserver(TAGDBOpenHelper.CONTENT_URI, true, observer);

//解除观察者getContentResolver().unregisterContentObserver(observer);

注册和解除可以根据需要, 比如分别放在Activity的onCreate()和onDestroy()方法中. 关于这个CONTENT_URI, 是自定义的, 如:

public static final String TABLE_NAME_TAG = "tag";public static final String AUTHORITY = "com.lichen.tagprovider";public static final Uri CONTENT_URI = Uri.parse("content://"+TAGDBOpenHelper.AUTHORITY+"/"+TABLE_NAME_TAG);

此Observer的目的可以说是监听或者观察这个URI的变化.


三. 在UI线程中, 用Handler接收来自Observer发出的Message, 更新UI.

@Overridepublic void handleMessage(Message msg) {    switch (msg.what) {            case TAGContentObserver.TAG_DB_CHANGE:            TextView tagNum = (TextView) findViewById(R.id.tag_total_num);            tagNum.setText("TAG总数: " + msg.arg1);            break;    }}

到这里, 注册观察者Observer, 数据变化后重新查询数据库, 得到结果异步用Handler来更新UI. 看起来好像齐全了, 其实还有谁在什么时候通知观察者数据变化了的问题.


四. 在ContentProvider中添加通知数据变化.

@Overridepublic Uri insert(Uri uri, ContentValues values) {    db = dbHelper.getWritableDatabase();    long rowId = db.insert(TAGDBOpenHelper.TABLE_NAME_TAG, "", values);    if (rowId > 0) {        Uri newUrl = ContentUris.withAppendedId(TAGDBOpenHelper.CONTENT_URI, rowId);        //通知数据变化        getContext().getContentResolver().notifyChange(newUrl, null);        return newUrl;    }    return null;}                                                                                                 @Overridepublic int delete(Uri uri, String where, String[] whereArgs) {    db = dbHelper.getWritableDatabase();    int count = 0;    switch (matcher.match(uri)) {    case TAGDBOpenHelper.TAG:        count = db.delete(TAGDBOpenHelper.TABLE_NAME_TAG, where, whereArgs);        break;    case TAGDBOpenHelper.TAG_ID:        long parseId = ContentUris.parseId(uri);        where = " _id = " + parseId ;        count = db.delete(TAGDBOpenHelper.TABLE_NAME_TAG, where, null);        break;    }    //通知数据变化    getContext().getContentResolver().notifyChange(uri, null);    return count;}                                                                                                 @Overridepublic Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {    db = dbHelper.getReadableDatabase();    int match = matcher.match(uri);    Cursor cursor = null;    switch (match) {    case TAGDBOpenHelper.TAG:        cursor = db.query(TAGDBOpenHelper.TABLE_NAME_TAG, null, null, null, null, null, null);        cursor.setNotificationUri(getContext().getContentResolver(), uri);//通知数据变化        break;    }    return cursor;}

这样, 这个TextView就可以实时监控并更新显示数据总数了.

本文出自 “” 博客,请务必保留此出处

转载于:https://my.oschina.net/lichen/blog/264858

你可能感兴趣的文章
我的Android进阶之旅------>Android关于dp(dip)、sp转px的工具类
查看>>
[Phoenix] 二、数据类型
查看>>
第三届中国互联网安全领袖峰会:聚焦新秩序下网络安全之道
查看>>
判断输入年份是否为闰年的另一种方法
查看>>
这家初创企业专做云安全即服务平台
查看>>
蚂蚁金服漆远谈大数据智能:有95%智能客服
查看>>
《2040大预言:高科技引擎与社会新秩序》——2.3 自我实现预言
查看>>
运用信息化手段建立管理“云平台”
查看>>
抱团发展成云服务厂商共识
查看>>
《高性能科学与工程计算》——3.5 算法分类和访存优化
查看>>
印国有电信企业BSNL致函印度电信部申请700 MHz频谱
查看>>
Cohesity扩大云软件产品组合 目标直指云未来
查看>>
阿里云跨界合作芒果TV 粉丝看明星也用云计算
查看>>
教你一招CRM成功实施的方法!
查看>>
数据中心网络攻击形态漫谈
查看>>
单元测试实施解惑(一)
查看>>
《编写高质量代码:改善c程序代码的125个建议》——建议18-2:整型变量应该直接与0进行比较...
查看>>
灵活的 WEB 下拉组件 TinySelect
查看>>
《CCNP ROUTE 300-101认证考试指南》——8.8节定义关键术语
查看>>
《软件建模与设计: UML、用例、模式和软件体系结构》一一1.1 软件建模
查看>>