1.内容观察者的介绍
内容观察者(ContentObserver)是用来观察Uri所代表的数据,当ContentObserver观察到指定Uri代表的数据发生变化时,就会触发ContentObserver的onChange()方法。此时在onChange()方法里使用ContentResolver可以查询到变化的数据。
上图表示,使用ContentObserver观察A应用的数据时,首先要在A应用的ContentProvider中调用ContentResolver的notifyChange()方法。调用了这个方法之后当数据发生变化时,它就会向“消息中心”发送数据变化的消息。然后C应用观察到“消息中心”有数据变化时,就会触发ContentObserver的onChange()方法
2.常用方法
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();
}
}
}