Android ContentObserver ContentProvider ContentResolver 综合使用

1,介绍:

【1】ContentObserver——内容观察者,目的是观察(捕捉)特定Uri引起的数据库的变化,做一些相应的处理,它类似于数据库技术中的触发器(Trigger),当ContentObserver所观察的Uri发生变化时,便会触发它。触发器分为表触发器、行触发器,

熟悉Content Provider(内容提供者)的应该知道,我们可以通过UriMatcher类注册不同类型的Uri,我们可以通过这些不同的

Uri来查询不同的结果。根据Uri返回的结果。

【2】ContentObserver不是四大组件不需要在androidmanifest 注册。

2,完成一个观察者的小demo 

1,应用1 (内容提供者)

【1】创建数据库

public class MyOpenHelper extends SQLiteOpenHelper {



    /**

     * @param context

     * name :数据库名字

     * factory: 游标工厂

     * version: 数据库的版本

     */

    public MyOpenHelper(Context context) {

        super(context, "account.db", null, 1);

    }



    //Called when the database is created for the first time. 当数据库第一次创建的时候调用 那么这个方法适合做表结构的初始化

    @Override

    public void onCreate(SQLiteDatabase db) {



        db.execSQL("create table info (_id integer primary key autoincrement,name varchar(20),phone varchar(20),money varchar(20))");

        db.execSQL("insert into info ('name','phone','money') values ('张三','138888','2000')");

        db.execSQL("insert into info ('name','phone','money') values ('李四','139999','5000')");

    }



    @Override

    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }

}

【2】AccountProvider 继承ContentProvider 重写方法,暴露QIUD方法。

   getContext().getContentResolver().notifyChange(uri, null);方法通知内容观察者

public class AccountProvider extends ContentProvider {



    // [1]定义一个urimatcher路径匹配器

    private static final UriMatcher sURIMatcher = new UriMatcher(

            UriMatcher.NO_MATCH);

    private static final int QUERYSUCESS = 0;

    private static final int INSERTSUCESS = 1;

    private static final int UPDATESUCESS = 2;

    private static final int DELETESUCESS = 3;

    private MyOpenHelper myOpenHelper;



    // [2]在静态代码块中添加路径

    static {

        /**

         * authority:要和你在清单文件里面声明authority一样

         *

         * URL:统一资源定位符 https://www.baidu.com/tieba Uri:统一资源标识符

         * com.itheima.db/query uri就是自己定义的一个路径 代表一个含义

         *

         */

       

    sURIMatcher.addURI("com.xiaoshuai.db", "query", QUERYSUCESS);

    sURIMatcher.addURI("com.xiaoshuai.db", "insert", INSERTSUCESS);

    sURIMatcher.addURI("com.xiaoshuai.db", "update", UPDATESUCESS);

    sURIMatcher.addURI("com.xiaoshuai.db", "delete", DELETESUCESS);



    }



    @Override

    public boolean onCreate() {

        myOpenHelper = new MyOpenHelper(getContext());



        return false;

    }



    // 把这个方法对外暴露出去

    @Override

    public Cursor query(Uri uri, String[] projection, String selection,

            String[] selectionArgs, String sortOrder) {

        // [1]获取一个匹配码

        int code = sURIMatcher.match(uri);

        if (code == QUERYSUCESS) {

            // 说明路径匹配成功 把这个方法实现 实际上就是在这个方法对数据库进行查询的操作

            SQLiteDatabase db = myOpenHelper.getReadableDatabase();

            Cursor cursor = db.query("info", projection, selection,selectionArgs, null, null, sortOrder);

            

            //[2]当对数据库进行查询操作后 自己主动的发送一条消息

            getContext().getContentResolver().notifyChange(uri, null);

            

            return cursor;

        } else {

            // 代表路径匹配失败

            return null;

            // throw new IllegalArgumentException("哥们路径不正确 ,请检查路径");

        }

    }

    @Override

    public String getType(Uri uri) {

        return null;

    }

    @Override

    public Uri insert(Uri uri, ContentValues values) {

        int code = sURIMatcher.match(uri);

        if (code == INSERTSUCESS) {

            // 代表路径匹配成功 把insert方法实现

            SQLiteDatabase db = myOpenHelper.getReadableDatabase();

            // 代表新插入行的id

            long insert = db.insert("info", null, values);

            Uri uri2 = Uri.parse("com.itheima.insert/" + insert);

            if (insert > 0) {

                //[2]当对数据库进行查询操作后 自己主动的发送一条消息

                getContext().getContentResolver().notifyChange(uri, null);

            }

            return uri2;

        } else {

            return null;

        }

    }



    @Override

    public int delete(Uri uri, String selection, String[] selectionArgs) {

        int code = sURIMatcher.match(uri);

        if (code == DELETESUCESS) {

            // 代表路径匹配成功 把insert方法实现

            SQLiteDatabase db = myOpenHelper.getReadableDatabase();

            // 代表删除的行数

            int delete = db.delete("info", selection, selectionArgs);

            if (delete > 0) {

                //[2]当对数据库进行查询操作后 自己主动的发送一条消息

                getContext().getContentResolver().notifyChange(uri, null);

            }

            return delete;

        } else {

            return 0;

        }

    }

    @Override

    public int update(Uri uri, ContentValues values, String selection,

            String[] selectionArgs) {

        int code = sURIMatcher.match(uri);

        if (code == UPDATESUCESS) {

            // 代表路径匹配成功 把insert方法实现

            SQLiteDatabase db = myOpenHelper.getReadableDatabase();

            // 代表更新的行数

            int update = db.update("info", values, selection, selectionArgs);

            if (update > 0) {

                //[2]当对数据库进行查询操作后 自己主动的发送一条消息

                getContext().getContentResolver().notifyChange(uri, null);

            }

            return update;

        } else {

            return 0;

        }

    }

}

【3】Android Manifest中声明provider

<provider

android:authorities="com.xiaoshuai.db"

android:exported="true"

android:name=".AccountProvider" />

  

2,应用2 (内容解析者)

【1】获取内容解析者,通过URI 调用QIUD 方法 进行操作 ContentResolver 

  public void click(View v) {

        Log.e("Main", "我被点击了。不是我的错");

        ContentResolver resolver = getContentResolver();

        Uri uri = Uri.parse("content://com.xiaoshuai.db/query");

        Cursor cursor = resolver.query(uri, null, null, null, null);

        if (cursor != null && cursor.getCount() > 0) {

            // ★★★ 想取出数据必须移动游标

            while (cursor.moveToNext()) {

                String name = cursor.getString(1);

                String money = cursor.getString(3);



                Log.e("Main", "第二个应用~~name:" + name + "----" + money);

            }

            cursor.close();

        }

    }



//add

    public void click1(View v) {

        // [1]由于第一个应用的数据库系统已经通过内容提供者暴露出来 所以可以直接通过内容解析者操作数据库

        Uri uri = Uri.parse("content://com.xiaoshuai.db/insert");

        // [2]创建contentValues

        ContentValues values = new ContentValues();

        // 参数1 是表的列名:

        values.put("name", "王五");

        values.put("money", "100");

        // [3]往数据库里面插入了一条数据

        Uri insert = getContentResolver().insert(uri, values);



        Log.e("Main","insert" +insert);

    }



    public void click2(View v) {

        Uri uri = Uri.parse("content://com.xiaoshuai.db/delete");

        int delete = getContentResolver().delete(uri, "name=?",

                new String[] { "王五" });

        Toast.makeText(getApplicationContext(), "删除了" + delete + "行", Toast.LENGTH_LONG).show();

    }



    public void click3(View v) {

        Uri uri = Uri.parse("content://com.xiaoshuai.db/update");

        ContentValues values = new ContentValues();

        values.put("money", "10000");

        int update = getContentResolver().update(uri, values, "name=?",

                new String[] { "王五" });

        Toast.makeText(getApplicationContext(), "修改了了" + update + "行", Toast.LENGTH_SHORT)

                .show();

    }

}

3,应用3 (内容观察者)

【1】  getContentResolver().registerContentObserver(uri, true, new MyContentObserver(new Handler())); 注册内容观察者进行监听。

public class MainActivity extends Activity {



    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        //[1]注册内容观察者  还是使用内容解析者去注册

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

        //[2]注册内容观察者  参数二:如果是false 那么第一个参数的uri必须是一个精确的uri true:可以不用是一个精确的uri

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

        

    }



    //定义内容观察者

    private class MyContentObserver extends ContentObserver{



        public MyContentObserver(Handler handler) {

            super(handler);

        }

        //当我们观察的内容发生变化 这个方法就执行

        @Override

        public void onChange(boolean selfChange) {

            System.out.println("哈哈  数据库被人操作了");

            super.onChange(selfChange);

        }

    }

}



猜你喜欢

转载自blog.csdn.net/Cricket_7/article/details/84863861