Android 内容观察者的原理

拦截短信,比如当发短信的时候,就把短信读取出来,当系统的短信发生变化的时候,大叫一声,把数据发送到公共的消息邮箱里面,我们的应用通过内容观察者观察公共的消息邮箱

获取ContentResolver对象,调用函数getContentResolver(),

调用ContentResolver对象的registerContentObserver(uri,notifyForDescendents,observer)方法,参数:Uri对象,是否精确uri(true不精确,false精确),observer对象 ContentObserver对象

因为ContentObserver是抽象类,因此我们写一个内部类来继承这个抽象类,必须实现构造函数,构造函数的Handler对象消息处理器稍后会讲,定义一个内部类MyObserver,实现父类的onChange()回调方法,观察到消息邮箱发生变化的时候会回调这个方法。

在这个回调函数里面,使用获取到短信内容,取最后一条,调用Cursor对象的moveToFirst()指针指向最后一条

系统应用是如何发出这个叫声的呢,获取ContentResolver对象,通过getContentResolver()方法,调用ContentResolver对象的notifyChange(uri,observer)方法,参数:uri随便定义,observer指定谁处理默认null

系统的很多应用进行通知通信都是通过这个公共消息邮箱机制来实现的

接下来实战一下,接着《Android 内容提供者的实现》中使用的项目作为基础,新建一个项目,并添加代码如下:

package com.wuyudong.observer;

import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.Context;
import android.database.ContentObserver;
import android.view.Menu;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Uri uri = Uri.parse("content://com.wuyudong.db.personprovider/");

        getContentResolver().registerContentObserver(uri, true,
                new MyObserver(new Handler()));

    }

    private class MyObserver extends ContentObserver {

        public MyObserver(Handler handler) { // handler 是一个消息处理器
            super(handler);

        }

        @Override
        public void onChange(boolean selfChange) {
            // TODO Auto-generated method stub
            System.out.println("haha,数据库的内容变化了!!!");
            super.onChange(selfChange);
        }

    }

}

并修改PersonDBProvider.java中的代码:

    public Uri insert(Uri uri, ContentValues values) {
        if (matcher.match(uri) == INSERT) {
            // 返回查询的结果集
            SQLiteDatabase db = helper.getWritableDatabase();
            db.insert("person", null, values);
            getContext().getContentResolver().notifyChange(uri, null);
        } else {
            throw new IllegalArgumentException("路径不匹配,不能执行插入操作");
        }
        return null;
    }

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        if (matcher.match(uri) == DELETE) {
            // 返回查询的结果集
            SQLiteDatabase db = helper.getWritableDatabase();
            int result = db.delete("person", selection, selectionArgs);
            db.close();
            if (result > 0) {
                getContext().getContentResolver().notifyChange(uri, null);
            }
        } else {
            throw new IllegalArgumentException("路径不匹配,不能执行删除操作");
        }
        return 0;
    }

这样在每次点击按钮的时候,都会打印相关数据库数据被修改的提示

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值