为了在应用程序之间交换数据,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),