目前见过最全的解析
ContentResolver直译为内容解析器,和ContentProvider成对出现。
程序间数据的共享是通过Provider/Resolver进行的。提供数据(内容)的就叫Provider,Resovler提供接口对这个内容进行解读。
onCreate() 、getType() 、query() 、insert() 、update()、delete()
提供的方法和参数都和ContentProvider呈对应关系
public void registerContentObserver(Uri uri, boolean notifyForDescendents,
IContentObserver observer) {
mRootNode.addObserverLocked(uri, observer,
notifyForDescendents, mRootNode,
Binder.getCallingUid(), Binder.getCallingPid());
}
uri:针对对有变化的感兴趣进行监听的URI
notifyForDescendents:true表示以uri前缀开始的任何变化都进行通知;false表示完全匹配才进行通知;
observer:IContentObserver接口,提供了一个方法onChange,变化发生时Cursor需要更新时调用;还可以extends ContentObserver ↓通过监听下面这个方法
@Override
public void onChange(boolean selfChange) {
}
使用此ContentService的registerContentObserver接口注册Observer,通过指定Uri可以仅对数据库中感兴趣的数据有变化时,进行监听。具体实现细节可以看下ContentService源代码中是如何构建一个树形结构来管理观察者对感兴趣数据的监听,看到根节点就是上述的mRootNode构建了一颗大树。
public void notifyChange(@NonNull Uri uri, @Nullable ContentObserver observer) {
notifyChange(uri, observer, true /* sync to network */);
}
作用:
观察 Uri引起 ContentProvider 中的数据变化 & 通知外界(即访问该数据访问者)
当ContentProvider 中的数据发生变化(增、删 & 改)时,就会触发该 ContentObserver类
截取自here
查询
Uri uri = Uri.parse("content://sms/");
ContentResolver resolver = getContentResolver();
//获取的是哪些列的信息
Cursor cursor = resolver.query(uri, new String[] { "address", "date", "type", "body" }, null, null, null);
if (cursor != null) {
StringBuffer sb = new StringBuffer();
while (cursor.moveToNext()) {
sb.append("联系人:" + cursor.getString(cursor.getColumnIndex("address")));
sb.append("\n时间:" + cursor.getString(cursor.getColumnIndex("date")));
sb.append("\n类型:" + cursor.getString(cursor.getColumnIndex("type")));
sb.append("\n内容:" + cursor.getString(cursor.getColumnIndex("body")));
sb.append("\n===============================\n");
}
tv_info.setText(sb.toString());
cursor.close();
}
插入
ContentValues values = new ContentValues();
values.put("address", "10086");//联系人
values.put("type", 1);//类型1是"收到"的短信
values.put("date", System.currentTimeMillis());//收到的时间
values.put("body", "您的余额还有1,000,000万元!");//内容
Uri returnUri = resolver.insert(Uri.parse("content://sms"), values);
if (returnUri != null) {
tv_info.setText(returnUri.toString());
if (returnUri.getPath().equals("/0")) {
Toast.makeText(this, "添加失败:" + returnUri.getPath(), Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "添加成功:" + returnUri.getPath(), Toast.LENGTH_SHORT).show();
}
}
数据刷新通知
// 步骤1:注册内容观察者,通过ContentResolver类进行注册,并指定需要观察的URI
// 在
ContentObserver getContentResolver().registerContentObserver(uri);
// 步骤2:当该URI的ContentProvider数据发生变化时,通知外界(即访问该ContentProvider数据的访问者)
public class UserContentProvider extends ContentProvider {
public Uri insert(Uri uri, ContentValues values) {
db.insert("user", "userid", values);
getContext().getContentResolver().notifyChange(uri, null);// 通知访问者
}
}
// 步骤3:解除观察者 ,同样需要通过ContentResolver类进行解除
getContentResolver().unregisterContentObserver(uri);