第9章 使用ContentProvider实现数据共享

来源:互联网 发布:薪酬优化 劳务外包 编辑:程序博客网 时间:2024/04/28 07:07
    为了在应用程序之间交换数据,Android提供了ContentProvider,当一个应用程序需要把自己的数据暴露给其他程序使用时,该应用程序就可以提供ContentProvider来实现,不管该应用程序是否启动,其他应用程序都可通过ContentResolver来操作暴露的数据。此书作者将ContentProvider类比成“网站”,这个网站以固定的Uri对外提供服务;而ContentResolver则可以当成是HttpClient,它可以向指定Uri发送“请求”(实际上是调用ContentResolver的方法),这种请求最后委托给ContentProvider处理,从而实现对“网站”(即ContentProvider)内部数据进行操作。理解了这一点,本章内容上手就很快。
上图!



【知识点】
·开发一个ContentProvider的步骤
    ①定义自己的ContentProvider类,需要继承Android提供的ContentProvider基类。
    ②向Android系统注册这个“网站”,就是在AndroidManifest.xml文件中注册这个ContentProvider,就像注册Activity一样,注册ContentProvider时需要为它绑定一个Uri。向Android系统中注册ContentProvider只要在<application.../>元素下添加如下子元素:
<!-- 下面配置中name属性指定ContentProvider类,authorities就相当于为该ContentProvider指定域名--><provider  android:name=".DictProvider"       android:authorities="org.lxj.provider.dictprovider"    android:exported="true"/>
    通过上面配置文件注册了ContentProvider之后,其它应用程序就可通过该Uri来访问DictProvider所暴露的数据了。

·Uri简介
    示例Uri:
content://org.crazyit.providers.dictprovider/words
    它可以分为三部分:
    content://:这个部分是Android的ContentProvider规定的,默认。
    org.lxj.crazyit.dictprovider:这个部分就是ContentProvider的authority。系统就是由这个部分来找到操作哪个ContentProvider。只要访问指定的ContentProvider,这个部分总是固定的。
    words:资源部分(或者说数据部分),当访问者需要访问不同资源时,这个部分是动态改变的。
为了将一个字符串转换为Uri,Android提供的Uri工具提供了parse()静态方法,示例代码如下:
 Uri uri=Uri.parse("content://org.lxj.crazyit.dictprovider/words");

·使用ContentResolver操作数据
    Context通过getContentResolver()方法来获取ContentResolver对象,一旦在程序中获得ContentResolver对象之后,接下来就可以调用ContentResolver的如下方法来操作数据: 
insert(Uri uri,ContentValues  values):根据Uri插入values对应的数据。
delete(Uri uri,String selection,String[ ]  selectionArgs):根据Uri删除select条件所匹配的全部记录。
update(Uri uri,ContentValues  values,String selection,String[ ] selectionArgs):根据Uri修改select条件所匹配的全部记录。 
query(Uri uri,String[ ]  projection,String selection,String[ ] selectionArgs,String sortOrder):根据Uri查询出select条件所匹配的全部记录,其中projection就是一个列名列表,表明只选择出指定的数据列。


·ContentProvider与ContentResolver的关系


·UriMatcher、ContentUris
UriMatcher:为了确定ContentProvider实际能处理的Uri,以及确定每个方法中Uri参数所操作的数据,Android为此提供的工具类,主要提供两个方法:
        void addURI(String authority,String path,int code):向UriMatcher对象注册Uri。
        int match(Uri uri):根据前面注册的Uri来判断指定Uri对应的标识码。
ContentUris:操作Uri字符串的工具类,主要提供两个方法:
        withAppendedld(uri,id):用于为路径加上ID部分。
        parseID(uri):用于从指定Uri中解析出所包含的的ID值。


·通过ContentProvider来获取Android内部的数据
    ①调用Activity的getContentResolver()来获取ContentResolver对象;
    ②根据需要调用ContentResolver的insert()、delete()、update()和query方法操作数据。
为了操作系统提供的ContentResolver,需要了解该ContentProvider的Uri以及该ContentProvider所操作的数据列的列明,可通过Android官方文档查阅。


·监听ContentProvider的数据改变
    开发ContentProvider时,不管实现了insert、delete、update方法哪一个,只要到导致了ContentProvider里数据的改变,程序就会调用如下代码来通知所有注册在该Uri上的监听者:
getCContext().getContentResolver().notifyChange(uri,null);
    为了在应用程序中监听ContentProvider数据的改变,需要利用Android提供ContentObserver基类。
监听ContentProvider数据改变的监听器需要继承ContentObserver类,并重写该基类所定义的onChange(boolean selfChange)方法--当它所监听的ContentProvider数据发生改变时,该onChange将会被触发。为了监听指定ContentProvider的数据变化,需要通过ContentResolver向指定Uri注册ContentObserver监听器,ContentResolver提供如下方法来注册监听器:
registerContentObserver(Uri uri,boolean notifyForDescendents,ContentObserver  observer)
其中的参数说明:
uri:该监听器所监听的ContentProvider的Uri。 
notifyForDescendents:如果该参数设为true,假如注册监听的Uri为content://abc,那么Uri为content://abc/xyz,content://abc/xyz/foo的数据改变时也会触发该监听器。如果为false,监听器只响应content://abc的触发。observer:监听器实例


【问题】
·问:这两章书的代码都经常用到Cursor这个类,在这里总结下
  答:学过Java的这样子说最容易理解,Cursor作用类似于java中resultSet,把查询到的结果集封装在一个Cursor对象当中。cursor就像是结果集上的一个游标,可以向前向后移动。详见http://blog.csdn.net/hejiero/article/details/18992863


5 0
原创粉丝点击