您的位置:首页 > 其它

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

2018-02-09 17:47 357 查看
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的callApplicationOnCrea
e7c5
te()来调用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()
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: