1. ContentProvider 概述
- ContentProvider 是一种内容共享型组件,它通过 Binder 向其他组件乃至其他应用提供数据
- 当 ContentProvicer 所在的进程启动时,ContentProvider 会同时启动并被发布到 AMS 中。此时 ContentProvider 的
onCreate()
方法要先于 Application 的onCreate()
方法而执行,这在四大组件中是一个少有的现象
2. ContentProvider 启动过程概述
当一个应用启动时,入口方法为 ActivityThread 的
main()
方法,main()
方法是一个静态方法,在main()
方法中会创建 ActivityThread 的实例并创建主线程的消息队列,然后在 ActivityThread 的attach()
方法中会远程调用 AMS 的attachApplication()
方法并将 ApplicationThread 对象提供给 AMSApplicationThread 是一个 Binder 对象 ,它的 Binder 接口是 IApplicationThread,它主要用于 ActivityThread 和 AMS 之间的通信
在 AMS 的
attachApplication()
方法中,会调用 ApplicationThread 的bindApplication()
方法,这个过程同样是跨进程完成的,bindApplication()
方法的逻辑会经过 ActivityThread 中的 mHandler 切换到 ActivityThread 中去执行,具体的方法是handleBindApplication()
在
handleBindApplication()
方法中,ActivityThread 会创建 Application 对象并加载 ContentProvider。需要注意的是,ActivityThread 会先加载 ContentProvicer,然后再调用 Application 的onCreate()
方法。整个流程图如下:以上是 ContentProvider 的启动过程,ContentProvider 启动后,外界就可以通过它所提供的增删改查这四个接口来操作 ContentProvider 中的数据源,即
insert()
、delete()
、update()
、query()
四个方法这四个方法都是通过 Binder 来调用的,外界无法直接访问 ContentProvider,它只能通过 AMS 根据 Uri 来获取对应的 ContentProvider 的 Binder 接口 IContentProvider,然后再通过 IContentProvider 来访问 ContentProvider 中的数据源
一般来说,ContentProvider 都应该是单实例的。ContentProvider 到底是不是单实例,这是由它的
android:multiprocess
属性来决定的。当android:multiprocess
为 false 时,ContentProvider 是单实例,这也是默认值;当androdi:multiprocess
为 true 时,ContentProvider 为多实例,此时在每个调用者的进程中都存在一个 ContentProvider 对象由于在实际开发中,并未发现多实例的 ContentProvider 的具体使用场景,官方文档中的解释是这样可以避免 进程间通信的开销,但是这在实际开发中仍然缺少使用价值。因此,可以简单认为 ContentProvider 都是单实例的