ActivityManagerService
,简称AMS,服务端对象,负责系统中所有Activity的生命 周期。 ActivityManagerService
进行初始化的时机很明确,就是在SystemServer
进程开启 的时候,就会初始化ActivityManagerService
。
下面介绍下Android系统里面的服务器和客户端的概 念。
其实服务器客户端的概念不仅仅存在于Web开发中,在Android的框架设计中,使 用的也是这一种模式。服务器端指的就是所有App共用的系统服务,比如我们这里 提到的ActivityManagerService
,和前面提到的PackageManagerService
、 WindowManagerService
等等,这些基础的系统服务是被所有的App公用的,当某 个App想实现某个操作的时候,要告诉这些系统服务,比如你想打开一个App,那 么我们知道了包名和MainActivity
类名之后就可以打开
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
ComponentName cn = new
ComponentName(packageName, className);
intent.setComponent(cn); startActivity(intent);
但是,我们的App通过调用startActivity()
并不能直接打开另外一个App,这个方法会 通过一系列的调用,最后还是告诉AMS说:“我要打开这个App,我知道他的住址和 名字,你帮我打开吧!”所以是AMS来通知zygote进程来fork一个新进程,来开启我 们的目标App的。这就像是浏览器想要打开一个超链接一样,浏览器把网页地址发 送给服务器,然后还是服务器把需要的资源文件发送给客户端的。
知道了Android Framework的客户端服务器架构之后,我们还需要了解一件事情, 那就是我们的App和AMS
(SystemServer
进程)还有zygote进程分属于三个独立的进 程,他们之间如何通信呢?
App与AMS
通过Binder进行IPC
通信,AMS
(SystemServer
进程)与zygote通过 Socket进行IPC
通信。后面具体介绍。
那么AMS
有什么用呢?在前面我们知道了,如果想打开一个App的话,需要AMS
去 通知zygote进程,除此之外,其实所有的Activity的开启、暂停、关闭都需要AMS
来控制,所以我们说,AMS
负责系统中所有Activity的生命周期。 在Android系统中,任何一个Activity的启动都是由AMS
和应用程序进程(主要是 ActivityThread
)相互配合来完成的。AMS
服务统一调度系统中所有进程的 Activity启动,而每个Activity的启动过程则由其所属的进程具体来完成。
4.Launcher
当我们点击手机桌面上的图标的时候,App就由Launcher开始启动了。但是,你有 没有思考过Launcher到底是一个什么东西? Launcher本质上也是一个应用程序,和我们的App一样,也是继承自Activity packages/apps/Launcher2/src/com/android/launcher2/Launcher.java
public final class Launcher extends Activity
implements View.OnClickListener, OnLongClickListener, La uncherModel.Callbacks, View.OnTouchListener {
}
Launcher实现了点击、长按等回调接口,来接收用户的输入。既然是普通的App, 那么我们的开发经验在这里就仍然适用,比如,我们点击图标的时候,是怎么开启 的应用呢?捕捉图标点击事件,然后startActivity()
发送对应的Intent请求呗!是的,Launcher也是这么做的,就是这么easy!
5.Instrumentation和ActivityThread
每个Activity都持有Instrumentation
对象的一个引用,但是整个进程只会存在一个 Instrumentation
对象。 Instrumentation
这个类里面的方法大多数和Application
和 Activity
有关,这个类就是完成对Application
和Activity
初始化和生命周期的工具 类。Instrumentation
这个类很重要,对Activity生命周期方法的调用根本就离不开 他,他可以说是一个大管家。
ActivityThread
,依赖于UI线程。App和AMS
是通过Binder传递信息的,那么 ActivityThread
就是专门与AMS
的外交工作的。
6.ApplicationThread
前面我们已经知道了App的启动以及Activity的显示都需要AMS
的控制,那么我们便 需要和服务端的沟通,而这个沟通是双向的。
客户端–>服务端
而且由于继承了同样的公共接口类,ActivityManagerProxy
提供了与 ActivityManagerService
一样的函数原型,使用户感觉不出Server是运行在本地还是 远端,从而可以更加方便的调用这些重要的系统服务。
服务端–>客户端
还是通过Binder通信,不过是换了另外一对,换成了ApplicationThread
和 ApplicationThreadProxy
。
他们也都实现了相同的接口IApplicationThread
private class ApplicationThread extends ApplicationThreadNative {
}
public abstract class ApplicationThreadNative extends Binder i mplements IApplicationThread{
}
class ApplicationThreadProxy implements IApplicationThread {
}
好了,前面罗里吧嗦的一大堆,介绍了一堆名词,可能不太清楚,没关系,下面结 合流程图介绍。
三、启动流程
1.创建进程
① 先从Launcher的
startActivity()
方法,通过Binder通信,调用ActivityManagerService
的startActivity
方法。
② 一系列折腾,最后调用startProcessLocked()
方法来创建新的进程。
③ 该方法会通过前面讲到的socket通道传递参数给Zygote进程。Zygote孵化自身。 调用ZygoteInit.main()
方法来实例化ActivityThread
对象并最终返回新进程的pid。
④ 调用ActivityThread.main()
方法,ActivityThread
随后依次调用Looper.prepareLoop()
和Looper.loop()
来开启消息循环。
方法调用流程图如下:
更直白的流程解释:
①App发起进程:
当从桌面启动应用,则发起进程便是Launcher所在进程;当从某 App内启动远程进程,则发送进程便是该App所在进程。发起进程先通过binder发送 消息给system_server
进程;
②system_server进程:
调用Process.start()
方法,通过socket向zygote进程发送创 建新进程的请求;
③zygote进程:
在执行ZygoteInit.main()
后便进入runSelectLoop()
循环体内,当有 客户端连接时便会执行ZygoteConnection.runOnce()
方法,再经过层层调用后fork 出新的应用进程;
④新进程:
执行handleChildProc
方法,最后调用ActivityThread.main()
方法。
2.绑定Application
上面创建进程后,执行ActivityThread.main()
方法,随后调用attach()方法。
将进程和指定的Application
绑定起来。这个是通过上节的ActivityThread
对象中调用 bindApplication()
方法完成的。该方法发送一个BIND_APPLICATION
的消息到消息 队列中, 最终通过handleBindApplication()
方法处理该消息. 然后调用 makeApplication()
方法来加载App的classes到内存中。
方法调用流程图如下:
更直白的流程解释:
(如果看不懂AMS,ATP等名词,后面有解释)
3.显示Activity界面
经过前两个步骤之后, 系统已经拥有了该application
的进程。 后面的调用顺序就是 普通的从一个已经存在的进程中启动一个新进程的activity了。
实际调用方法是realStartActivity()
, 它会调用application线程对象中的 scheduleLaunchActivity()
发送一个LAUNCH_ACTIVITY
消息到消息队列中, 通过 handleLaunchActivity()
来处理该消息。在 handleLaunchActivity()
通过 performLaunchActiivty()
方法回调Activity的onCreate()
方法和onStart()
方法,然后通 过handleResumeActivity()
方法,回调Activity的onResume()
方法,最终显示Activity 界面。
更直白的流程解释:
四、Binder通信
简称:
ATP: ApplicationThreadProxy
AT: ApplicationThread
AMP: ActivityManagerProxy
AMS: ActivityManagerService
图解:
① system_server进程中调用
startProcessLocked
方法,该方法最终通过socket方式, 将需要创建新进程的消息告知Zygote进程,并阻塞等待Socket返回新创建进程的pid;
② Zygote进程接收到system_server发送过来的消息, 则通过fork的方法,将zygote 自身进程复制生成新的进程,并将ActivityThread
相关的资源加载到新进程app process,这个进程可能是用于承载activity等组件;
③ 在新进程app process向servicemanager
查询system_server进程中binder服务端 AMS, 获取相对应的Client端,也就是AMP. 有了这一对binder c/s对, 那么app process便可以通过binder向跨进程system_server发送请求,即attachApplication()
④system_server
进程接收到相应binder操作后,经过多次调用,利用ATP向app process
发送binder请求, 即bindApplication. system_server
拥有ATP/AMS, 每一个 新创建的进程都会有一个相应的AT/AMP,从而可以跨进程 进行相互通信. 这便是进 程创建过程的完整生态链。
以上大概介绍了一个APP从启动到主页面显示经历的流程,主要从宏观角度介绍了 其过程,具体可结合源码理解。
(顺手留下GitHub链接,需要获取相关面试等内容的可以自己去找)
https://github.com/xiangjiana/Android-MS
(VX:mm14525201314)
PDF和源码获取
接,需要获取相关面试等内容的可以自己去找**)
https://github.com/xiangjiana/Android-MS
(VX:mm14525201314)