在Android中,我们的应用有的时候需要对外提供数据接口,可以有如下几种方法:1)AIDL 2)Broadcast 3)ContentProvider。
使用Broadcast,我们不需要任何接口描述,只要协议文档就可以了,但是这种方式不直接而且是异步的;
使用ContentProvider我们不需要接口描述,只需要知道协议,同时这种方式是同步的,使用方便。下面是ContentProvider简单介绍:
Android中的Contentprovider机制可支持在多个应用中存储和读取数据。这也是跨应用共享数据的唯一方式。在android系统中,没有一个公共的内存区域,供多个应用共享存储数据。
ContentProvider介绍:
Android有一个独特之处就是,数据库只能被它的创建者所使用,其他的应用是不能访问的,所以如果想实现不同应用之间的数据共享,就不得不用content
通常,一个应用程序可以创建自己的数据,这个数据对该应用程序来说是私有的,外界根本看不到,也不知道数据是如何存储的,是使用数据库还是使用文件,或是通过网上获得,这些一切都不重要,重要的是外界可以通过ContentProvider这一套标准及统一的接口和这个程序里的数据打交道,例 如:添加(insert)、删除(delete)、查询(query)、修改(update)。
android自身也提供了几个现成的content
总的来说:
1、ContentProvider为存储和读取数据提供了统一的接口
2、使用ContentProvider,应用程序可以实现数据共享
3、android内置的许多数据都是使用ContentProvider形式,供开发者调用的(如视频,音频,图片,通讯录等)
Uri介绍:
1、每一个ContentProvider都拥有一个公共的Uri,这个Uri用于表示这个ContentProvider提供的数据
Android的ContentProvider URI有固定的形式:content://contract/people
标准前缀:固定为content : //
URI标识:它定义了是哪个Content Provider提供这些数据。对于第三方应用程序,为了保证URI标识的唯一性,它必须是一个完整的、小写的类名。这个标识在元素的authorities属性中说明:一般是定义该ContentProvider的包.类的名称(主机名/Authority)
路径:people 具体的资源类型
路径的构建应根据业务而定,如下:
要操作person表中id为10的记录,可以构建这样的路径:/person/10
要操作person表中id为10的记录的name字段, person/10/name
要操作person表中的所有记录,可以构建这样的路径:/person
要操作xxx表中的记录,可以构建这样的路径:/xxx
当然要操作的数据不一定来自数据库,也可以是文件、xml或网络等其他存储方式,如下:
要操作xml文件中person节点下的name节点,可以构建这样的路径:/person/name
如果要把一个字符串转换成Uri,可以使用Uri类中的parse()方法,如下:
Uri uri = Uri.parse("content://com.ljq.provider.personprovider/person")
在Android中广泛应用URI,而不是URL。URL标识资源的物理位置,相当于文件的路径;而URI则是标识资源的逻辑位置,并不提供资源的具体位置。比如说电话薄中的数据,如果用URL来标识的话,可能会是一个很复杂的文件结构,而且一旦文件的存储路径改变,URL也必须得改动。但是若是URI,则可以用诸如content://contract/people这样容易记录的逻辑地址来标识,而且并不需要关心文件的具体位置,即使文件位置改动也不需要做变化,当然这都是对于用户来说,后台程序中URI到具体位置的映射还是需要程序员来改动的。
UriMatcher类使用介绍
因为Uri代表了要操作的数据,所以我们经常需要解析Uri,并从Uri中获取数据。Android系统提供了两个用于操作Uri的工具类,分别为UriMatcher和ContentUris 。掌握它们的使用,会便于我们的开发工作。
//常量UriMatcher.NO_MATCH表示不匹配任何路径的返回码
UriMatcher
//如果match()方法匹配content://com.ljq.provider.personprovider/person路径,返回匹配码为1
sMatcher.addURI("com.ljq.provider.personprovider", "person", 1);//添加需要匹配uri,如果匹配就会返回匹配码
//如果match()方法匹配content://com.ljq.provider.personprovider/person/230路径,返回匹配码为2
sMatcher.addURI("com.ljq.provider.personprovider", "person/#", 2);//#号为通配符
switch (sMatcher.match(Uri.parse("content://com.ljq.provider.personprovider/person/10"))) {
}
注册完需要匹配的Uri后,就可以使用sMatcher.match(uri)方法对输入的Uri进行匹配,如果匹配就返回匹配码,匹配码是调用addURI()方法传入的第三个参数,假设匹配content://com.ljq.provider.personprovider/person路径,返回的匹配码为1
ContentUris类使用介绍
ContentUris类用于操作Uri路径后面的ID部分,它有两个比较实用的方法:
withAppendedId(uri, id)用于为路径加上ID部分:
Uri uri = Uri.parse("content://com.ljq.provider.personprovider/person")
Uri resultUri = ContentUris.withAppendedId(uri, 10);
//生成后的Uri为:content://com.ljq.provider.personprovider/person/10
parseId(uri)方法用于从路径中获取ID部分:
Uri uri = Uri.parse("content://com.ljq.provider.personprovider/person/10")
long personid = ContentUris.parseId(uri);//获取的结果为:10
创建ContentProvider共享应用程序中的数据
实现ContentProvider的过程:(创建)
1、定义一个COTENT_URI常量
2、定义一个类,继承ContentProvider
3、实现query(),delete(),update(),insert(),onCreate(),getType()方法
public class PersonContentProvider extends ContentProvider{
}
如果操作的数据属于集合类型,那么MIME类型字符串应该以vnd.android.cursor.dir/开头,
例如:要得到所有person记录的Uri为content://com.ljq.provider.personprovider/person,那么返回的MIME类型字符串应该为:"vnd.android.cursor.dir/person"。
如果要操作的数据属于非集合类型数据,那么MIME类型字符串应该以vnd.android.cursor.item/开头,
例如:得到id为10的person记录,Uri为content://com.ljq.provider.personprovider/person/10,那么返回的MIME类型字符串为:"vnd.android.cursor.item/person"。
4、在AndroidMainfest.xml中申明,ContentProvider采用了authorities(主机名/域名)对它进行唯一标识,你可以把ContentProvider看作是一个网站
<</SPAN>manifest.... >
</</SPAN>manifest>
使用已经提供ContentProvider的应用程序中的数据:
应用可以通过一个唯一的ContentResolver
ContentResolver
然后就可以用ContentResolver提供的方法来使用需要的content
contentprovider的用户都不可能直接访问到contentprovider实例,只能通过ContentResolver在中间代理。Contentprovider返回的数据结构,是类似JDBC的ResultSet,在android中,是Cursor对象。
ContentProvider负责
组织应用程序的数据;
向其他应用程序提供数据;
ContentResolver则负责
获取ContentProvider提供的数据;
修改/添加/删除更新数据等;
一个程序可以通过实现一个ContentProvider的抽象接口将自己的数据完全暴露出去,而且ContentProviders是以类似数据库中表的方式将数据暴露
ContentProvider应该是Android在系统启动时就创建了,否则就谈不上数据共享了。 这就要求在AndroidManifest.XML中使用元素明确定义。