ContentProvider总结及Loader的使用

来源:互联网 发布:线割编程招聘 编辑:程序博客网 时间:2024/04/25 08:03

概述

ContentProvider(内容提供者)是Android中的四大组件之一。主要用于程序间数据的共享(IPC的一种).
它提供了一套完整的机制,允许一个程序访问另一个应用程序,并且保证数据的安全性.
我们知道在Android中常见的数据存储方式有sharedpreferences,文件和数据库等,但是数据的访问方式会因为存储方式的不同而不同.
而且这些数据只能在应用内使用,而ContentProvider允许在程序间实现数据的共享,并且提供好了统一了数据的访问方式.

ContentResolver

访问内容提供器中共享的数据,需要借助通过ContentResolver,其中context.getContentResolver()方法可以获取到ContentResolver实例,
ContentResolver提供了一系列方法来对数据进行CRUD操作.

URI

统一资源标识符,结构和HTTP形式的URL是一样的.
代表了要操作的数据,每一个ContentProvider都拥有一个公共的URI,不能重复

<prefix>://<authority>/<data_type>/<id>

其中,<prefix>的值永远为content,不可更改

<authority>唯一标识符,用来定位ContentProvider,一般为自定义Provider的全路径名,保证唯一

<data_type>/<id>代表资源路径,如/person/2代表person表中id为2的数据

MIME

用于指定某个扩展名的文件用一种应用程序来打开,如application/pdf,text/css等,Android中的MIME类型有两种
* 多条记录
vnd.android.cursor.dir/vnd.xxx
* 单条记录
vnd.android.cursor.item/vnd.xxx

其中包含类型和子类型,/前面的类型是Android定义好的,不可更改,子类型中vnd.后面的可以随意指定.在使用Intent时,会用到MIME这玩意,根据Mimetype打开符合条件的活动。

自定义Contentprovider

  • 继承ContentProvider,并重写其中的一些方法,

其中OnCreate()方法在Provider初始化的时候执行

getType(URI uri)用于返回某一URI对应的MIME类型,运行在Binder线程池中

还有其他一些操作CRUD操作,运行在Binder线程池中

  • UriMatcher

用于冠关联Provider中的自定义URI和URI_CODE,通过addURI()将相应的Path和Code联系起来,通过match(uri)得到相应的CODE.

//为外部程序准备好一个所有地址匹配集合static{      uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);      uriMatcher.addURI(PROVIDER_NAME, "students", STUDENTS);      uriMatcher.addURI(PROVIDER_NAME, "students/#", STUDENT_ID);   }// 取得数据的类型,此方法会在系统进行URI的MIME过滤时被调用。@Override public String getType(Uri uri) {    switch (uriMatcher.match(uri)){       /**       * Get all student records        */       case STUDENTS:       return "vnd.android.cursor.dir/vnd.example.students";       /**        * Get a particular student       */       case STUDENT_ID:       return "vnd.android.cursor.item/vnd.example.students";       default:       throw new IllegalArgumentException("Unsupported URI: " + uri);   }}
  • ContentUris
    用于操作Uri路径后面的ID部分

其中withAppendedId(uri, id)用于为路径加上ID部分:

Uri uri = Uri.parse("content://com.example.provider.College/students")  Uri resultUri = ContentUris.withAppendedId(uri, 10);   //生成后的Uri为:content://com.example.provider.College/students/10  

parseId(uri)方法用于从路径中获取ID部分:

Uri uri = Uri.parse("content://com.example.provider.College/students/10 ")  long personid = ContentUris.parseId(uri);//获取的结果为:10 
  • 配置清单文件
<provider        android:authorities="com.bobomee.android.contentproviderdemo"        android:name=".BookContentProvider"/>

监听ContentProvider变化

如果ContentProvider的访问者需要知道ContentProvider中的数据发生变化,可以在ContentProvider发生数据变化时调用getContentResolver().notifyChange(uri, null)来通知注册在此URI上的访问者,

Uri insertUri = Uri.withAppendedPath(uri, "/" + rowId);      Log.i(TAG, "insertUri:"+insertUri.toString());      //发出数据变化通知(book表的数据发生变化)      getContext().getContentResolver().notifyChange(uri, null);      return insertUri;

Loader

Loader是3.0引入的API,可以优雅的实现异步,常用于Activity和Fragment中异步加载数据.防止引起内存泄漏,不仅如此,Loader还实时监听数据源,在配置发生改变后不会重新查询等.

Loader是一个抽象类,实际使用时,我们使用的是AsyncTaskLoader与CursorLoader,使用Loader,需要了解LoaderManager及LoaderCallbacks的API.关于Loader的详细介绍Android之Loader介绍

其中CursorLoader和Contentprovider一起使用再合适不过了

最后使用Contentprovider的小Demo:ProviderDemo

参考文章:

ContentProvider和Uri详解
Android - Content Providers
我是这样理解Android开发中的contentprovider的
Android开发教程:Android数据储存之ContentProvider
android ContentProvider使用详解
Android之Loader介绍
Android中Loader及LoaderManager的使用(附源码下载)

0 0