理解ContentProvider、ContentResolver与ContentObserver的联系与区别
就是一种程序与程序之间交互的一种手段,提供者负责暴露方法,解析者负责操作数据,观察者充当后台的角色。
简单介绍如何使用:( 在SQLite数据库存储的基础上进行!! )
------ContentProvider内容提供者共享数据-------
程序A:
1.创建MyContentprovider(地址值一般为项目地址值,类似于对暗号)
2.指定Uri
Uri为内容提供者中的数据建立了唯一标识符。三部分组成:scheme、authority、path
例如:content://com.example.sqlitesample/insert
★这里使用UriMatcher类
3.重写类中的相关操作方法(判断,操作数据) 这里拿query(查询)举例
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
// TODO: Implement this to handle query requests from clients.
if (matcher.match(uri) == QUERY_OK){ //判断uri是否匹配
SQLiteDatabase db = myHelper.getReadableDatabase();
Cursor cursor = db.query("information", null, null, null, null, null, null);
return cursor;
}else {
throw new UnsupportedOperationException("uri地址匹配错误");
}
}
-----ContentResolver内容解析者操作数据--------
接下来创建程序B
1.创建页面,ui设计,控件初始化
2.项目B中获取内容解析者对象(getContentResolver()),根据指定Uri操作应用A的数据
这里以查询为例:
@Override
public void onClick(View v) {
ContentResolver resolver = getContentResolver(); //使用ContentResolver 解析应用A共享出来的数据
switch (v.getId()) {
case R.id.button:
Uri uri = Uri.parse("content://com.example.sqlitesample/query"); //将字符串转化为URI地址
Cursor cursor = resolver.query(uri, null, null, null, null, null);
List data = new ArrayList<>(); //创建Friend bean类 将数据成对存入集合
while (cursor.moveTonext()){ //利用游标将数据取出
String name = cursor.getString(1);
String phone = cursor.getString(2);
data.add(new Friend(name,phone));
}
StringBuilder builder = new StringBuilder(); //将数据进行拼接
for (int i = 0; i < data.size(); i++) {
builder.append("n姓名:"+ data.get(i).getName()+" 电话:"+data.get(i).getPhone());
}
textView.setText(builder.toString());
运行截图:(数据是在应用A上事先存好的)
-----ContentObserver内容观察者监测数据变化------
检测内容提供者
1.修改程序A的内容提供者,在其对外共享的数据操作中(例如:插入),当成功修改了数据,通知消息中心数据发生了改变(getContext().getContentResolver().notifyChange())
2.创建程序C,自定义MyContentObserver类(内容观察者,extends ContentObserver)
重写onChang()方法处理监测到有数据变化要做的事;
class MyContentObserver extends ContentObserver{
public MyContentObserver(Handler handler) {
super(handler);
}
@Override
public void onChange(boolean selfChange) {
super.onChange(selfChange);
Log.i("abc", "程序A中数据被修改");
}
}
3.在项目C中注册内容观察者(getContentResolver().registerContentObserver()),观察指定Uri中数据的变化 ,并重写onDestroy()方法注销观察者
private MyContentObserver observer;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
observer = new MyContentObserver(new Handler());
Uri uri = Uri.parse("com.example.sqlitesample");
//注册内容观察者
getContentResolver().registerContentObserver(uri, true, observer);// true表示该地址下的派生类 insert、query..
}
@Override
protected void onDestroy() {
super.onDestroy();
//注销内容观察者
getContentResolver().unregisterContentObserver(observer);
}
最后同时运行程序A、B、C测试就行了



