content provider(2)

160 阅读2分钟

「这是我参与11月更文挑战的第15天,活动详情查看:2021最后一次更文挑战

5. 具体使用:

image.png

5.1:

统一资源标识符(URI)

l 定义:Uniform Resource Identifier,即统一资源标识符

l 作用:唯一标识 ContentProvider 和 其中的数据

 

l 外界进程通过 URI 找到对应的ContentProvider 和 其中的数据,再进行数据操作

l 具体使用:  URI分为 系统预置 & 自定义,分别对应系统内置的数据(如通讯录、日程表等等)和自定义数据库

image.png

设置URI Uri uri = Uri.parse("content://com.carson.provider/User/1")  上述URI指向的资源是:名为 com.carson.providerContentProvider 中表名 为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:

image.png

image.png

FirstProvider:

image.png

phone:

image.png

结果:

image.png

总结:

其实MainActivity中调用的

contentResolver的”query”,”update”,”delete”,”insert”方法,

其实返回的是FirstProvider中的

ContentProvider的”query”,”update”,”delete”,”insert”返回值;