关于ContentProvider,ContentResolver的学习笔记

来源:互联网 发布:excel同列找出重复数据 编辑:程序博客网 时间:2024/05/18 13:46

一.定义

     ContentProvider(内容提供者)是一个可以实现跨进程数据共享的接口

    ContentResolver(内容解析器) 获取ContentProvider的共享数据的类

    简单点来说就是:在A应用中使用ContentProvider将数据共享,在B应用中使用ContentResolver获取A应用共享出来的数据

二.用法

    ContentProvider共享的数据是其所在App的数据库中的数据,这里我们定义一个ContentProvider类看看

    public class TestProvider  extends ContentProvider{

    private static UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);  
    private final static int USER= 1;

    private final static int USER2=2;
    static {  

        //①
        uriMatcher.addURI("android.com.testcontentprovider","user",USER);  

        //②

        uriMatcher.addURI("android.com.testcontentprovider","user/#",USER2);  
    } 


    @Override
    public boolean onCreate() {
        return false;
    }


    @Nullable
    @Override
    public String getType(Uri uri) {
        return null;
    }
    
    @Nullable
    @Override
    public Cursor query(Uri uri, String[] strings, String s, String[] strings1, String s1) {
        return null;
    }
    
    @Nullable
    @Override
    public Uri insert(Uri uri, ContentValues contentValues) {
        return null;
    }


    @Override
    public int delete(Uri uri, String s, String[] strings) {
        return 0;
    }


    @Override
    public int update(Uri uri, ContentValues contentValues, String s, String[] strings) {
        return 0;
    }
}

    我们会发现这里面除了getType(Uri uri)全是操作数据库的方法,ContentProvider就是通过这些方法将数据共享给另一个APP操作的,其中的实现我就不写代码了,基本就是sqlite数据库的东西。

    UriMatcher:在ContentProvider中这是最重要的一个东西,它只有2个方法,void addURI(String authority,String path,int code)int match(Uri uri)

   void addURI(String authority,String path,int code),authority,ContentProvider的唯一标识符,在其他应用中如何定位到你所需要的某个app中的数据,就是通过这个authority来识别的,所以说它是唯一的,一般是ContentProvider的类的全名。path为一个路径,可以设置通配符,#表示数字,*表示字符,一般格式为tableName/或者tableName/#。Code为自定义的一个数字,它的用法和uriMatcher的第二个方法有关。

  

   int Match(Uri uri) 这个方法的返回值就是addUri()方法中的code

ContentResolver:通过getContentResolver()方法获取实例,如果需要查询另一个应用(B)中的数据,就可通过这样的方法来获取:

   Cursor cursor=getContentResolver().query(uri, projection,selection, selectionArgs,sortOrder);

我们会发现这和我们平常用的sqlite查询方法参数基本一样,唯一的差别就是这里传入了一个Uri而非表名,这里的这个Uri起的作用其实就是和表名一样,通过它我们可以定位到我们想要共享数据的ContentProvider,我们这里调用的query方法,其实就是调用uri所定位的provider的query方法,获取我们所要的cursor.

 这里的uri有个比较固定的格式:

   //③

   content://android.com.testcontentprovider/user

 或者

   //④

   content://android.com.testcontentprovider/user/1


   content://表示从ContentProvider中获取数据

   android.com.testcontentprovider:就是之前我们所定义的ContentProvider中的authority

   user:要查询的表

   user/1:查询user表中id为1的数据,这里我们必须要在创建数据表的时候定义一个id字段并且设置为 primary key autoincreament;

   当我们用③跨进程获取数据的时候就会匹配到ContentProvider中的①,④就会匹配到②,他们是一一对应的关系。

    getType(Uri uri):在contentProvider中有一个getType()方法,它的作用是什么呢?getType返回的字符串,如果URI针对的是单条数据,则返回的字符串以vnd.android.cursor.item/开头;如果是多条数据,则以vnd.adroid.cursor.dir/开头。在跨进程获取数据的时候,这个方法即使我们不重写,也不会影响我们使用ContentProvider,它主要的作用还是减少系统的开销,我们知道③和④一个是返回的集合,一个是单个数据,如果我们这里不写任何代码,在获取数据的时候会有一个验证的过程,而如果我们在这里阐明数据时单个还是集合类型,就会减少系统的开销。但是如果getType(Uri uri)方法用来做activity的隐式跳转的时候就必须指定其MIME类型为隐式跳转的activity中的MIME类型,不然就会出现MIME类型不匹配的错误


    上面我们已经把工作做得差不多了,剩下就是配置权限了,ContentProvider必须在Mainfest里面注册。

    //如果自定义了外部访问权限就需要声明,注意这里是permission,不是uses-permission

    <permission android:name="android.com.testcontentprovider.pers"/>

    <provider
            //唯一标识符 
            android:authorities="android.com.testcontentprovider"
            //是否可被外界访问
            android:exported="true"
            //自定义的外部权限,可有可无
            android:permission="android.com.testcontentprovider.pers"
            android:name=".MyContentProvider" >

     在调用端进行调用的时候,如果有自定义的外部权限就需要进行权限声明,注意这里是uses-permission

    <uses-permission android:name="android.com.testcontentprovider.pers"/>



阅读全文
0 0
原创粉丝点击