说说provider的启动原理




acquireExistingProvider:查询应用端本地是否有这个ContentProvider记录
如果应用端本地没有ContentProvider,就通过AMS返回一个holder,使用这个holder在本地安装ContentProvider

下图是本地找ContentProvidr

ProviderClientRecord与AMS里的ContentProviderRecord 是对应的
binder对象对应的binder实体进程挂了的话,这个binder也就无用了
handleUnstableProviderDiedLocked:处理善后工作,从本地缓存清楚,告知AMS做相关清除
下图是 本地找不到ContentProvider时,如何从AMS里找

通常4大组件在AMS里都有对应的Record,ActivityRecord,ServiceRecord,BroadcastReceiverRecord,ContentProviderRecord
ContentProvider的两种工作模式:
ContentProvider不能运行在调用者进程(运行在自己的进程),AMS将ContentProvider的binder对象转发给调用者,调用者通过这个binder对象执行增删改查操作
ContentProvider能运行在调用者进程


canRunHere: provider是否能运行在调用者进程
provider存在多个实例,因为它可以运行在自己的进程和调用者的进程,如果在调用者进程,就不需要IPC通信,效率提高
holder.provider:binder对象,如果holder.provider != null,应用端直接使用它执行增删改查操作,如果holder.provider == null,应用端就会在本地创建一个provider实例,这样就不会跟provider的进程通信了

localProvider.attachInfo: 给provider赋予Context,调用provider的onCreate函数
installProviderAuthoritiesLocked(provider, localProvider, holder):创建一个ProviderClientRecord对象
将创建出来的pr加入到本地缓存mLocalProviders和mLocalProviderByName里
总结

上面部分:
Provider启动时将binder对象发布到AMS,应用要使用这个provider时向AMS发起请求,AMS返回这provider的binder,应用通过binder执行增删改查操作
下面部分:
Provide可以运行在应用进程(app.uid == provider.uid && (provider.multiprocess || app.packageName == provider.packageName)),应用进程直接创建一个provider对象,免去IPC通信。

capr.canRunHere: 返回cpr.newHolder, 调用者用这个holder创建一个provider实例
if( proc != null && proc.thread != null) {
provider所在进程启动了,但provider还没将binder发布到AMS,scheduleInstallProvider:想provider请求binder对象
}else {
provider所在进程没启动,先启动进程
}
mLaunchingProvider:AMS正等着这些provider发布binder

cpr.provider: binder对象,cpr.provider == null,说明这个ContentProvider还没将binder对象发布到AMS
provider 怎么发布自己的binder对象
1. 应用启动时主动发布provider的binder对象
2. AMS请求应用端发布binder对象
下图为应用启动时主动发布provider的binder对象

generateApplicationProvidersLocket:AMS向Package manager service查询provider列表
CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: AMS 等 provider发布binder,如果在规定时间内没有发布,就超时了
thread.bindApplication(processName, appInfo, providers, ...): 此处带上providers是让应用端安装这些provider,在安装的过程中会把binder对象发布到AMS里。
下图为应用端处理AMS调用bindApplication

在主线程执行

ContentProviderHolder里有provider的binder对象
AMS内

AMS主动想应用请求发布binder,应用端的处理如下

installContentProviders(mInitialApplication, Lists.newArrayList(info)): 依次安装provider,创建provider对象,调用provider的onCreate函数,最后发布binder对象到AMS

provider进程没有启动的情况
bindApplication:创建application,应用端的provider全部初始化一遍,安装provider,创建provider对象,调用onCreate函数
publishContentProvider:发布binder到AMS

provider进程已经启动的情况
scheduleInstallProvider:请求provider发布binder
说说Provider的启动原理
Provider启动过程,已经各个组件之间怎么通信的?
参考前面的流程图进行讲解
说一下Provider的生命周期
Provider是怎么初始化的?上下文是怎么初始化的?生命周期是怎么回调的?怎么发布到AMS?
说说Provider有多个实例的情况以及原理
网友评论