ContentProvider
安卓应用程序默认是无法获取到其他程序的数据,这是安卓安全学的基石(沙盒原理)。但是经常我们需要给其他应用分享数据,内容提供者就是一个这种可以分享数据给其他应用的接口。
可以简单的理解为,内容提供者就是一个可以在不同应用程序间共享数据的组件,相当于一个中间人,一个程序把数据暴露给这个中间人,另一个则通过这个中间人获取相应的数据.
下面的这张图片能更直观的显示:
ContentProvider
中的getContext
和AndroidTestCast
中的getContext
方法一样,都是一个模拟的上下文,必须在该类初始化之后才会调用setContext
方法将context
设置成自己的成员变量中记录,
所以对于获取getContext
的时候只能放在方法内,不能放到成员位置,因为在成员上时是null,而在方法内调用时该类就会已经初始化完了-
ContentProvider
中的query()
后不能关闭数据库,因为其他的应用在调用该query
方法时需要继续使用该返回值Cursor
,所以不能关闭数据库,因为数据库关闭之后Cursor
就不能用了,
Cursor
中保存的数据其实是数据库的一个引用,如果数据库关了Cursor
就不能找到里面的数据了,Cursor.close()
只是释放Cursor
用到的资源。说到这里就多数一句
According to Dianne Hackborn (Android framework engineer) there is no need to close the database in a content provider.
以为内容提供者是因为进程启动时便加载,之后就一直存在,当进程销毁
释放资源时会去关闭数据库。 -
如果数据是
SQLiteDatabase
,表中必须有一个_id
的列,用来表示每条记录的唯一性。
-
继承
ContentProvider
,并实现相应的方法。 - 在清单文件中进行注册,并且指定其authorities
- 使用内容提供者获取数据,使用
ContentResolver
去操作ContentProvider
,ContentResolver
用于管理ContentProvider
实例,
并且可实现找到指定的ContentProvider
并获取里面的数据
内容观察者
内容观察者的原理:
How a content provider actually stores its data under the covers is up to its designer. But all content providers implement a common interface for
querying the provider and returning results — as well as for adding, altering, and deleting data.
It's an interface that clients use indirectly, most generally through ContentResolver objects.
You get a ContentResolver by calling getContentResolver() from within the implementation of an Activity or other application component:
You can then use the ContentResolver's methods to interact with whatever content providers you're interested in.
- 一方使用内容观察者去观察变化
- 一方在发生变化的时候去发送改变的消息
对于一些系统的内容提供者内部都实现了该步骤,如果是自己写程序想要暴露就必须要加上该代码。