美文网首页
Android Framework学习之Provider的启动原

Android Framework学习之Provider的启动原

作者: 一只二凡子 | 来源:发表于2022-12-14 09:00 被阅读0次

说说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有多个实例的情况以及原理

相关文章

网友评论

      本文标题:Android Framework学习之Provider的启动原

      本文链接:https://www.haomeiwen.com/subject/ahwhqdtx.html