第九章 四大组件的工作过程
SystemServer:是一个系统进程
ServiceManager:是一个BinderPool
Activty继承自ContextThemeWrapper;
ContextThemeWrapper继承自ContextWrapper;
ContextWrapper继承自Context;
Context:是一个抽象类。上下文对象声明了要做哪些事情,但它只是一个空壳,是一个综合的环境,现在还并没有具体的成员来做这些事情
ContextWrapper:它也是一个Context,不同的是它的内部有一个成员mBase(类型是ContextImpl,是在Activity启动时,通过attach方法赋值的),很多事情是由这个mBase来做的
ContextThemeWrapper:它也是一个Context,不同的是它的内部也有一些成员,一些事情由这些成员来做
Activity:它也是一个Context,不同的是它的内部也有一些成员,一些事情由这些成员来做
Activity的工作过程
用户进程调用系统进程的Binder:ActivityManagerService继承ActivityManagerNative,ActivityManagerNative实现IActivityManager,IActivityManager在系统进程里进行关于四大组件的各种操作;
系统进程调用用户进程的Binder:ApplicationThread继承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()