内容观察者(ContentObserver)是用来观察Uri所代表的数据,当ContentObserver观察到指定Uri代表的数据发生变化时,就会触发ContentObserver的onChange()方法。此时在onChange()方法里使用ContentResolver可以查询到变化的数据。
上图表示,使用ContentObserver观察A应用的数据时,首先要在A应用的ContentProvider中调用ContentResolver的notifyChange()方法。调用了这个方法之后当数据发生变化时,它就会向“消息中心”发送数据变化的消息。然后C应用观察到“消息中心”有数据变化时,就会触发ContentObserver的onChange()方法
public void ContentObserver(Handler handler):ContentObserver的派生类都需要调用该构造方法。参数可以是主线程Handler(可以更新UI ),也可以是任何Handler对象。
public void onChange(boolean selfChange):当观察到的Uri代表的数据发生变化时,会触发该方法。
ContentProvider通过delete()、insert()、update()会使数据发生变化,因此使用ContentObserver同样需要观察这三个方法,并且需要在ContentProvider的这三个方法中调用ContentResolver的notifyChange()方法,如下代码:
public Uri insert(Uri uri, ContentValues values) { if (matcher.match(uri) == INSERT) { //匹配Uri路径 SQLiteDatabase db = helper.getWritableDatabase(); db.insert("person", null, values); getContext().getContentResolver(). notifyChange(PersonDao.messageuri, null); } else { //匹配失败 throw new IllegalArgumentException("路径不匹配,不能执行插入操作"); } return null; }接下来在应用中注册观察者,并监听数据变化
public class MainActivity extends Activity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ContentResolver resolver = getContentResolver(); Uri uri = Uri.parse("content://aaa.bbb.ccc"); resolver.registerContentObserver( uri, true, new MyObserver(new Handler())); } private class MyObserver extends ContentObserver{ public MyObserver(Handler handler) { super(handler); } public void onChange(boolean selfChange) { super.onChange(selfChange); Toast.makeText(MainActivity.this, "数据库的内容变化了.", 1).show(); Uri uri = Uri.parse("content://aaa.bbb.ccc"); ContentResolver resolver = getContentResolver(); Cursor cursor = resolver.query(uri, new String[] { "address","date","type", "body" }, null, null, null); cursor.moveToFirst(); String address = cursor.getString(0); String body = cursor.getString(3); Log.v("MyObserver","body"); cursor.close(); } } }