相关类的关系与作用
访问 ContentProvider 其实就是一次 Binder 通讯。
那么,到底是怎么实现通讯的的呢?为了方便后面源码的分析,先来展示相关类的关系图以及作用。
classDiagram
class ContentInterface{
+query()
+insert()
+delete()
+update()
}
class ContentProvider{
-Transport mTransport
}
class Binder
class ContentProviderNative{
+onTransact()
}
class IContentProvider{
+query()
+insert()
+delete()
+update()
}
class IInterface{
+IBinder asBinder()
}
class ContentProviderProxy{
-IBinder mRemote
}
class Transport{
+query()
+insert()
+delete()
+update()
}
class IBinder{
+onTransact()
}
<<Interface>> ContentInterface
<<Interface>> IInterface
<<Interface>> IContentProvider
<<Abstract>> ContentProviderNative
<<Interface>> IBinder
<<Abstract>> ContentProvider
IInterface ..|> IContentProvider
ContentInterface ..|> ContentProvider
Binder --|> ContentProviderNative
IBinder --|> Binder
IContentProvider ..|> ContentProviderNative
IContentProvider ..|> ContentProviderProxy
ContentProviderNative --|> Transport
ContentProvider *-- Transport : 内部类
这张类关系图,很好的说明了 Binder 通讯的过程,用语言反而有点解释不清的感觉,因此我这里大致说下 Binder 通讯的过程
- ContentProviderProxy 是 BP( Binder Proxy )端,客户端通过它发起访问 ContentProvider 的。
- ContentProvider 有一个成员变量 mTransport,它的类型是 Transport。Transport 是 BN( Binder Native )端,当收到一次 Binder 通讯后,它交给 ContentProvider 来处理。
如果读者了解底层的 Binder 架构,那这里的类关系图就非常容易理解。
那么,有些读者可能会很好奇,在上层为何不用 AIDL 自动生成架构的类呢?因为 AIDL 自动生成的类以及函数,无法完整实现 ContentProvider 的通讯,因此必须手动定义这些类,并实现相关函数。
这里给了我们一个启示,AIDL 还真不是万能的,所以,我们需要具备手动写 Binder 上层架构的能力。
ContentProvider 架构
我们知道 Binder 的 C/S 架构图如下
graph TD
Server --> |注册Binder|ServiceManager
client --> |查询Binder|ServiceManager
然而 ContentProvider 的 Binder 管理者不是 ServiceManager,而是 system_server,因此架构图如下
graph TD
宿主 --> |发布provider|system_server
客户端 --> |获取provider|system_server
宿主发布 provider ,其实就是向 system_server 注册用于通讯的 Binder,system_server 会保存这个 Binder。
当客户端向 system_server 获取访问 ContentProvider 接口时,system_server 会把 Binder 传递给客户端,客户端会把 Binder 转化为接口,然后通过这个接口,就可以实现对 ContentProvider 的访问。
约定
为了方便后续写文章,先达成几个约定
- 我会经常使用 provider 这个单词。在宿主 App 中代表 ContentProvider,在客户端 app 中代表 provider 接口。总之,在不同的时候代表不同的意思,大家注意意会。
- 宿主端,代表 ContentProvider 所在的 App。
- 客户端,代表访问 ContentProvider 的 App。
- 服务端,指的是 system_server 端。