第九章 四大组件的工作过程

SystemServer:是一个系统进程
ServiceManager:是一个BinderPool


Activty继承自ContextThemeWrapper;
ContextThemeWrapper继承自ContextWrapper;
ContextWrapper继承自Context;

Context:是一个抽象类。上下文对象声明了要做哪些事情,但它只是一个空壳,是一个综合的环境,现在还并没有具体的成员来做这些事情

ContextWrapper:它也是一个Context,不同的是它的内部有一个成员mBase(类型是ContextImpl,是在Activity启动时,通过attach方法赋值的),很多事情是由这个mBase来做的

ContextThemeWrapper:它也是一个Context,不同的是它的内部也有一些成员,一些事情由这些成员来做

Activity:它也是一个Context,不同的是它的内部也有一些成员,一些事情由这些成员来做


Activity的工作过程

用户进程调用系统进程的BinderActivityManagerService继承ActivityManagerNative,ActivityManagerNative实现IActivityManager,IActivityManager在系统进程里进行关于四大组件的各种操作;
系统进程调用用户进程的BinderApplicationThread继承ApplicationThreadNative,ApplicationThreadNative实现IApplicationThread,IApplicationThread在用户进程里进行关于四大组件的各种操作;
ActivityThread就是封装了在主线程中关于四大组件的各种操作的类,方便我们在主线程中进行关于四大组件的各种操作。

1、调用Activity的startActivity()

这里写图片描述

2、startActivity()有好几种重载方式,但最终都会调用startActivityForResult()

这里写图片描述

3、Instrumentation的execStartActivity()如下

这里写图片描述

1)上面的ActivityManagerNative.getDefault()如下

这里写图片描述

上面说的拿取关于Activity的Binder,定义如下。它的实现类是ActivityManagerService

这里写图片描述

2)checkStartActivityResult()检查启动Activity的结果,如果启动异常,会抛异常,比如Activity没有在Manifest注册

4、RPC调用服务端的AMS的startActivity(),在服务端进程中(即系统进程)的调用会经过如下过程:

这里写图片描述

5、ActivityStackSupervisor的realStartActivityLocked()中有如下代码:

这里写图片描述

ApplicationThread是AcitivityThread的内部类,它的定义如下

这里写图片描述

6、RPC调用用户进程的ApplicationThread的scheduleLaunchActivity()。
在此方法内部会发送一个启动Activity的消息交由Handler处理,这个Handler定义在ActivityThread内部:H。
最终处理消息时会调用ActivityThread的handleLaunchActivity()

7、ActivityThread的handleLaunchActivity()如下:

这里写图片描述

8、ActivityThread的performLaunchActivity()做了以下事情:
1)创建Activity对象。
通过Instrumentation的newActivity()使用类加载器创建Activity对象
2)创建Application对象(如果没有的话)
通过LoadedApk的makeApplication()来尝试创建Application对象。创建过程和Activity一样,然后会通过Instrumentation的callApplicationOnCreate()来调用Application的onCreate()
3)通过Activity的attach()来给Activity关联、初始化一些重要数据,比如Context、Window
这里写图片描述
4)调用Activity的onCreate()
mInstrumentation.callActivityOnCreate()。由于Activity的onCreate()已经被调用,意味着Activity已经完成了整个启动过程。


Service的启动过程

1、从ContextWrapper的startActivity()开始

这里写图片描述

2、然后是ContextImpl里面startActivity()的实现

这里写图片描述

3、在远程AMS中会调用mServices(ActiveServices,是辅助AMS进行Service管理的类)的
startServiceLocked()===》startServiceInnerLocked()===》bringUpServiceLocked()
==>realStartServiceLocked()

4、realStartServiceLocked()如下

这里写图片描述

5、scheduleCreateService()里会发消息,然后通过handleCreateService()处理。handleCreateService()做了如下事情:
1)通过类加载器创建Service实例
2)创建Application对象(如果没有的话),调用其onCreate()
3)通过Activity的attach()来给Activity关联、初始化一些重要数据,比如Context(ContextImpl)
4)调用onCreate()
5)将Service对象存储到ActivityThread的一个列表中
这里写图片描述

6、scheduleServiceArgs()里会发消息,然后通过handleServiceArgs()处理,里面会调用Service的
onStartCommand()

注:服务端和客户端各有一个mServices对象。服务端是ActiveServices,是辅助AMS进行Service管理的类;客户端是ArrayMap,用来存储Service对象。


Service的绑定过程

1、从ContextWrapper的startActivity()开始

这里写图片描述

2、然后会调用ContextImpl的bindServiceCommon()

这里写图片描述

ServiceConnection、ServiceDispatcher、InnerConnection(IServiceConnection)的关系:
服务的绑定可能是跨进程的,必须通过Binder来让服务端调用我们客户端的方法。这个Binder在这里就是IServiceConnection,而它的实现类就是InnerConnection,InnerConnection持有
ServiceDispatcher,而ServiceDispatcher又持有ServiceConnection,从而服务端可以调用
ServiceConnection的方法。
可以通过LoadedApk的getServiceDispatcher()得到ServiceConnection对应的InnerConnection
这里写图片描述
上图的mServices定义如下:
这里写图片描述
ServiceDispatch内部保存了ServiceConnection和InnerConnection对象

这里写图片描述

3、在远程AMS中会调用ActiveServices的bindServiceLocked()===>bringUpServiceLocked()
===》realStartServiceLocked()

这里写图片描述

4、create和启动方式一样,不同的是
这里写图片描述

5、同样,会在Service客户端用H发送消息,然后会交由handleBindService()处理
这里写图片描述

6、AMS的publishService()
这里写图片描述

7、RPC调用客户端的InnerConnection的connected()
这里写图片描述

8、ServiceDispatcher的connected()

这里写图片描述

这里写图片描述


广播的注册过程

广播的注册过程分为静态注册和动态注册,其中静态注册的广播在应用安装时由系统自动完成注册,具体来说是由PMS(PackageManagerService)来完成整个注册过程的,除了广播以外,其他三大组件也都是在应用安装时由PMS解析并注册的。
这里只分析动态注册的过程。

1、从ContextWrapper的registerReceiver()开始

这里写图片描述

2、ContextImpl的registerReceiver()调用了自己的registerReceiverInternal()

这里写图片描述

参照绑定Service的过程:

这里写图片描述

3、AMS的registerReceiver()看起来很长,其中重要的就是会把远程的InnerReceiver对象以及IntentFilter对象存储起来,这样整个广播的注册过程就完成了。如下:

这里写图片描述


广播的发送和接收过程

发送广播时,AMS会查找出匹配的广播接收者并将广播发送给它们处理。广播的发送有几种类型:普通广播、有序广播、粘性广播,特性不同,但是流程类似,因此这里只讨论普通广播的实现。

1、ContextWrapper的sendBroadcast(),实际调用ContextImpl的sendBroadcast()

这里写图片描述

2、服务端的broadcastIntent()调用了broadcastIntentLocked(),在此方法代码的最开始有如下一行

这里写图片描述

也就是说默认情况下广播不会发给已经停止的应用。有两种标记位:

这里写图片描述

如果需要调起未启动的应用,那么只需要为广播的Intent添加FLAG_INCLUDE_STOPPED_PACKAGES标记即可,当两个标记位共存时,以这个为准。

在broadcastIntentLocked的内部,会根据intent-filter查找出匹配的广播接收者并将其添加到BroadcastQueue中,接着BroadcastQueue会将广播发送给相应的广播接收者

这里写图片描述

3、接着看BroadcastQueue中广播的发送过程的实现
这里写图片描述

processNextBroadcast()对普通广播的处理如下:

这里写图片描述

deliverToRegisteredReceiverLocked()内部调用performReceiveLocked()

这里写图片描述

4、ApplicationThread的scheduleRegisteredReceiver()通过InnerReceiver来实现广播的接收

这里写图片描述

InnerReceiver的performReceive()会调用LoadedApk.ReceiverDispather的performReceiver(),
LoadedApk.ReceiverDispather的performReceiver()的实现如下:

这里写图片描述

Aras的run()中有如下代码:

这里写图片描述


ContentProvider的工作过程

当ContentProvider所在的进程启动时,ContentProvider会同时启动并被发布到AMS中。需要注意的是,ContentProvider的onCreate()要先于Application的onCreate()而执行,这在四大组件中是一个少有的现象。具体原因往下看即可知道。

访问ContentProvider需要通过ContentResolver,ContentResolver是一个抽象类,通过Context的getContentResolver()获取的实际上是ApplicationContentResolver对象。ApplicationContentResolver类继承了ContentResolver并实现了ContentResolver中的抽象方法。
当ContentProvider所在的进程未启动时,第一次访问它时就会触发ContentProvider的创建,当然这也伴随着ContentProvider所在进程的启动。

以query方法为例:

1、ContentResolver的query()首先会获取IContentProvider对象。最终会通过ApplicationContentResolver的acquireProvider()来获取:

这里写图片描述

ActivityThread的acquireProvider()如下:

这里写图片描述

2、如果目标ContentProvider未启动,AMS会先启动ContentProvider。ContentProvider被启动时会伴随着进程的启动,在AMS中首先会启动ContentProvider所在的进程,然后再启动ContentProvider。
启动进程是由AMS的startProcessLocked()来完成的,其内部主要是通过Process的start()来完成一个新进程的启动,新进程启动后其入口方法为ActivityThread的main(),如下:

这里写图片描述

3、Activtiy的attach()会将ApplicationThread对象通过AMS的attachApplication()跨进程传递给AMS。
AMS的attachApplication()调用了attachApplicationLocked(),attachApplicationLocked()中又调用了ApplicationThread的bindApplication()。
ActivityThread的bindApplication()会发送一个BIND_APPLICATION类型的消息给mH,mH是一个Handler,它收到消息后会调用ActivityThread的handleBindApplication()。
handleBindApplication()完成了Application的创建以及ContentProvider的创建,可以分为以下四个步骤:

1)创建ContextImpl和Instrumentation:

这里写图片描述

2)创建Application对象

这里写图片描述

3)启动当前进程的ContentProvider并调用其onCreate()

installContentProviders()完成了ContentProvider的启动工作

这里写图片描述

下面我们看一下ContentProvider对象的创建过程,即installProvider()

这里写图片描述

这里写图片描述

4)调用Application的onCreate()

这里写图片描述

4、经过以上步骤我们就可以通过AMS来访问这个ContentProvider了。这里的ContentProvider不是原始的ContentProvider,而是ContentProvider的Binder类型的对象IContentProvider。IContentProvider的具体实现是ContentProviderNative和ContentProvider.Transport,其中ContentProvider.Transport继承了
ContentProviderNative。

其它应用会通过AMS获取到ContentProvider的Binder对象即IContentProvider,而IContentProvider的实现者实际上是ContentProvider.Transport。因此其它应用调用IContentProvider的query()时最终会以进程间通信的方式调用到ContentProvider.Transport的query()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值