「这是我参与11月更文挑战的第15天,活动详情查看:2021最后一次更文挑战」
5. 具体使用:
5.1:
统一资源标识符(URI)
l 定义:Uniform Resource Identifier,即统一资源标识符
l 作用:唯一标识 ContentProvider 和 其中的数据
l 外界进程通过 URI 找到对应的ContentProvider 和 其中的数据,再进行数据操作
l 具体使用: URI分为 系统预置 & 自定义,分别对应系统内置的数据(如通讯录、日程表等等)和自定义数据库
设置URI Uri uri = Uri.parse("content://com.carson.provider/User/1") 上述URI指向的资源是:名为 com.carson.provider的ContentProvider 中表名 为User 中的 id为1的数据
// 特别注意:URI模式存在匹配通配符* & # *:匹配任意长度的任何有效字符的字符串
// 以下的URI 表示 匹配provider的任何内容 content://com.example.app.provider/* // #:匹配任意长度的数字字符的字符串
// 以下的URI 表示 匹配provider中的table表的所有行 content://com.example.app.provider/table/#
5.2
Android 提供了3个用于辅助ContentProvide的工具类:
· ContentUris UriMatcher ContentObserver
① ContentUris类
作用:操作 URI
核心方法有两个:withAppendedId() &parseId()
向URI追加一个id 从URI中获取ID
② UriMatcher类
作用: 在ContentProvider 中注册URI , 根据 URI 匹配 ContentProvider 中对应的数据表
核心方法有两个: addURI(“授权信息”,”表名”,”注册名URI_CODE”) 和 match(URI uri)
步骤1: 初始化UriMatcher对象,
UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
//常量UriMatcher.NO_MATCH = 不匹配任何路径的返回码 // 即初始化时不匹配任何东西
步骤2:在ContentProvider中注册URI(addURI());
int URI_CODE_a = 1;
int URI_CODE_b = 2;
matcher.addURI("cn.scu.myprovider", "user1", URI_CODE_a); matcher.addURI("cn.scu.myprovider", "user2", URI_CODE_b);
// 若URI资源路径 = content://cn.scu.myprovider/user1 ,则返回注册码URI_CODE_a
// 若URI资源路径 = content://cn.scu.myprovider/user2 ,则返回注册码URI_CODE_b
步骤3:根据URI匹配URI_CODE,从而匹配ContentProvider中相应的资源 (match());
@Override
public String getType(Uri uri) {
Uri uri = Uri.parse(" content://cn.scu.myprovider/user1");
switch(matcher.match(uri)){
// 根据URI匹配的返回码是URI_CODE_a
// 即matcher.match(uri) == URI_CODE_a
case URI_CODE_a: return tableNameUser1;
// 如果根据URI匹配的返回码是URI_CODE_a,则返回ContentProvider中的名为tableNameUser1的表
case URI_CODE_b: return tableNameUser2;
// 如果根据URI匹配的返回码是URI_CODE_b,则返回ContentProvider中的名为tableNameUser2的表
}
}
③ContentObserver
定义: 内容观察者
作用:观察Uri引起ContentProvider中数据的变化并通知外界(即该数据访问者)
当ContentProvider中的数据发生变化(增,删,改)的时候,就会出发ContentObserver类.
步骤一:注册内容观察者ContentObserver
getContentResolver().registerContentObserver(uri);
// 通过ContentResolver类进行注册,并指定需要观察的URI
步骤二:
当该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); // 通知访问者
}
}
步骤三:接触观察者
getContentResolver().unregisterContentObserver(uri);
// 同样需要通过ContentResolver类进行解除
例子:
MainActivity:
FirstProvider:
phone:
结果:
总结:
其实MainActivity中调用的
contentResolver的”query”,”update”,”delete”,”insert”方法,
其实返回的是FirstProvider中的
ContentProvider的”query”,”update”,”delete”,”insert”返回值;