Android开发笔记

1.6 清单文件中的provider

2018-09-10  本文已影响21人  littlezan

清单文件中的provider

ContentProvider,内容提供者,Android四大组件之一。主要作用,提供进程间数据共享和交互,为存储和获取数据提供统一的接口。ContentProvider底层采用Binder机制。

ContentProvider的数据共享主要用于操作本地数据库,外界通过ContentResolver提供的Api操作由ContentProvider共享的数据库的。

1. 在清单文件中声明需要共享的ContentProvider

        <provider
            android:name=".module.contentprovider.MyProvider"
            //Authority(授权信息) ContentProvider唯一标识符
            android:authorities="cn.scu.myprovider"
            android:exported="true"
            android:permission="scut.carson_ho.PROVIDER" />

2. 统一资源标识符(URI)

URI 英文全写,Uniform Resource Identifier,可以通过URI来标识ContentProvider,外界通过URI找到对应的ContentProvider操作数据库。

自定义URI:

content://cn.scu.myprovider/User/1

3. ContentProvider类

通过数据库组织数据,进程间共享数据的本质是:添加,删除,获取,更新,ContentProvider核心方法也是这4个操作。
外部进程在调用Content Provider方法的时候,是通过运行在ContentProvider进程的Binder线程池中,存在多线程并发的问题,需要线程同步。

ContentProvider 创建后,打开ContentProvider所在进程后,系统会调用ContentProvider的onCreate()方法,该方法运行在主线程。

3.1 ContentProvider 辅助类

三个辅助类:ContentUris,UriMatcher, ContentObserver

ContentUris类

ContentUris 主要用于 操作 URI。添加id和解析id

// withAppendedId()作用:向URI追加一个id
Uri uri = Uri.parse("content://cn.scu.myprovider/user") 
Uri resultUri = ContentUris.withAppendedId(uri, 7);  
// 最终生成后的Uri为:content://cn.scu.myprovider/user/7

// parseId()作用:从URL中获取ID
Uri uri = Uri.parse("content://cn.scu.myprovider/user/7") 
long personid = ContentUris.parseId(uri); 
//获取的结果为:7
UriMatcher类

主要有两个作用:

  1. 在ContentProvider 中注册URI
  2. 根据 URI 匹配 ContentProvider 中对应的数据表
    //1.初始化UriMatcher对象
    UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH); 
 
    //2.注册URI
    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); 
    
    //3.根据URI 匹配 URI_CODE,从而匹配ContentProvider中相应的资源
    @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类

//1. 注册内容观察者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. 解除观察者
 getContentResolver().unregisterContentObserver(uri);
 

4. ContentResolver类

通过URI 操作不同的ContentProvider中的数据。操作的方法与ContentProvider中方法相同,也是对数据库的增,删,查,改。

// 使用ContentResolver前,需要先获取ContentResolver
// 可通过在所有继承Context的类中 通过调用getContentResolver()来获得ContentResolver
ContentResolver resolver =  getContentResolver(); 

// 设置ContentProvider的URI
Uri uri = Uri.parse("content://cn.scu.myprovider/user"); 

// 根据URI 操作 ContentProvider中的数据
// 此处是获取ContentProvider中 user表的所有记录 
Cursor cursor = resolver.query(uri, null, null, null, "userid desc"); 
上一篇下一篇

猜你喜欢

热点阅读