本帖最后由 feng_home 于 2010-8-14 08:15 编辑 Android中的Content provider机制可支持在多个应用中存储和读取数据。这也是跨应用共享数据的唯一方式。在android系统中,没有一个公共的内存区域,供多个应用共享存储数据。 Android提供了一些主要数据类型的Content provider,比如音频、视频、图片和私人通讯录等。可在android.provider包下面找到一些android提供的Content provider。可以获得这些Content provider,查询它们包含的数据,当然前提是已获得适当的读取权限。 如果想公开自己的数据,那么可有两种办法:
ContentResolver实例带的方法可实现找到指定的Content provider并获取到Content provider的数据。ContentResolver的查询过程开始,Android系统将确定查询所需的具体Content provider,确认它是否启动并运行它。android系统负责初始化所有的Content provider,不需要用户自己去创建。实际上,content provider的用户都不可能直接访问到content provider实例,只能通过ContentResolver在中间代理。数据模型Content provider展示数据类似一个单个数据库表。其中:
表示这个uri指定一个content provider。如果你想创建自己的content provider,最好把自定义的URI设置为类的常量,这样简化别人的调用,并且以后如果更新URI也很容易。android定义了CONTENT_URI常量用于URI,比如:
要注意的是上面例子中的Contacts,已经在android 2.0及以上版本不赞成使用。查询Content provider要想使用一个content provider,需要以下信息:
其中第一个参数myPerson是Uri类型实例。如果需要查询的是指定行的记录,需要用_ID值,比如ID值为23,URI将是类似:
android提供了方便的方法,让开发者不需要自己拼接上面这样的URI,比如类似:
或者:
二者的区别是一个接收整数类型的ID值,一个接收字符串类型。其他几个参数:
返回值的内容
和JDBC中不同,没有直接通过列名获取列值的方法,只能先列名获取到列的整型索引值,然后再通过该索引值定位获取列的值。编辑数据可以通过content provider实现以下编辑功能:
在原有记录上增加值如果记录已经存在,可在记录上增加新的值,或者编辑已经存在的值。首先要过去到原来的值对象,然后要清除原有的值,然后像上面增加记录一样即可:
批量更新值批量更新一组记录的值,比如NY改名为Eew York。可调用ContenResolver.update()方法。删除记录如果是删除单个记录,调用ContentResolver.delete()方法,URI参数,指定到具体行即可。如果是删除多个记录,调用ContentResolver.delete()方法,URI参数指定Content provider即可,并带一个类似SQL的WHERE子句条件。这里和上面类似,不带WHERE关键字。创建自己的Content provider创建content provider,需要:
insert() update() delete() getType() onCreate()query()方法,返回值是Cursor实例,用于迭代请求的数据。Cursor是一个接口。android为该接口提供了一些只读的(和JDBC的ResultSet不一样,后者还提供可写入的可选特性)Cursor实现。比如SQLiteCursor,可迭代SQLite数据库中的数据。可以通过SQLiteDatabase类的query()方法获取到该Cursor实例。还有其他的Cursor实现,比如MatrixCursor,用于数据不是存储在数据库的情况下。因为Content provider可能被多个ContentResolver对象在不同的进程和线程中调用,因此实现Content provider必须考虑线程安全问题。作为良好的习惯,在实现编辑数据的代码中,要调用ContentResolver.notifyChange()方法,通知那些监听数据变化的监听器。在实现子类的时候,还有一些步骤可以简化Content provider客户端的使用:定义public static final Uri常量,名称为CONTENT_URI:
如果有多个表,它们也是使用相同的CONTENT_URI,只是它们的路径部分不同。 也就是说红色框部分是一致的。定义返回的列名,public static final,列名的值,比如使用SQLite数据库作为存储,对应表的列名。在文档中要写出各个列的数据类型,便于使用者读取。如果需要处理新的MIME数据类型,比如通过Intent的方式,并且带data的mimeType,那么需要在ContentProvider.getType()方法中进行处理。声明Content Provider创建Content Provider后,需要在manifest文件中声明,android系统才能知道它,当其他应用需要调用该Content Provider时才能创建或者调用它。语法类似:
android:name要写ContentProvider继承类的全名。android:authorities要写和CONTENT_URI常量的B部分(见上面图)。注意不要把上图C和D部分加到authorities中去。authorities是用来识别ContentProvider的,C和D部分实际上是ContentProvider内部使用的。 |
联系客服