zoukankan      html  css  js  c++  java
  • 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;
        }

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

  • 相关阅读:
    高性能队列设计
    线上 RTT 有 1/3 概率超过 3 秒,我用 arthas 查出元凶!
    你管这破玩意儿叫 token
    高可用与Zookeeper设计原理
    从应用层到网络层排查 Dubbo 接口超时全记录
    我是如何晋升专家岗的
    百亿数据,毫秒级返回,如何设计?--浅谈实时索引构建之道
    微信的原创保护机制到底是如何实现的
    AOP面试造火箭始末
    与一位转行做滴滴司机的前程序员对话引发的思考
  • 原文地址:https://www.cnblogs.com/wuyudong/p/5596369.html
Copyright © 2011-2022 走看看