Activity启动过程
-
ActivityManagerServices,简称AMS,服务端对象,负责系统中所有Activity的生命周期
-
ActivityThread,App的真正入口。当开启App之后,会调用main()开始运行,开启消息循环队列,这就是传说中的UI线程或者叫主线程。与ActivityManagerServices配合,一起完成Activity的管理工作
-
ApplicationThread,用来实现ActivityManagerService与ActivityThread之间的交互。在ActivityManagerService需要管理相关Application中的Activity的生命周期时,通过ApplicationThread的代理对象与ActivityThread通讯。
-
ApplicationThreadProxy,是ApplicationThread在服务器端的代理,负责和客户端的ApplicationThread通讯。AMS就是通过该代理与ActivityThread进行通信的。
-
Instrumentation,每一个应用程序只有一个Instrumentation对象,每个Activity内都有一个对该对象的引用。Instrumentation可以理解为应用进程的管家,ActivityThread要创建或暂停某个Activity时,都需要通过Instrumentation来进行具体的操作。
-
ActivityStack,Activity在AMS的栈管理,用来记录已经启动的Activity的先后关系,状态信息等。通过ActivityStack决定是否需要启动新的进程。
-
ActivityRecord,ActivityStack的管理对象,每个Activity在AMS对应一个ActivityRecord,来记录Activity的状态以及其他的管理信息。其实就是服务器端的Activity对象的映像。
-
TaskRecord,AMS抽象出来的一个“任务”的概念,是记录ActivityRecord的栈,一个“Task”包含若干个ActivityRecord。AMS用TaskRecord确保Activity启动和退出的顺序。如果你清楚Activity的4种launchMode,那么对这个概念应该不陌生。
zygote是什么?有什么作用?
当你的手机开机的时候,Linux的内核加载完成之后就会启动一个叫“init“的进程。在Linux System里面,所有的进程都是由init进程fork出来的,我们的zygote进程也不例外。
每一个App其实都是
- 一个单独的dalvik虚拟机
- 一个单独的进程
除了第一个zygote进程,其他应用所在的进程都是zygote的子进程
SystemServer是什么?有什么作用?它与zygote的关系是什么?
首先我要告诉你的是,SystemServer也是一个进程,而且是由zygote进程fork出来的。 系统里面重要的服务都是在这个进程里面开启的,比如 ActivityManagerService、PackageManagerService、WindowManagerService等等
ActivityManagerService是什么?什么时候初始化的?有什么作用?
ActivityManagerService,简称AMS,服务端对象,负责系统中所有Activity的生命周期。
ActivityManagerService进行初始化的时机很明确,就是在SystemServer进程开启的时候,就会初始化ActivityManagerService。
Android系统里面的服务器和客户端的概念。
其实服务器客户端的概念不仅仅存在于Web开发中,在Android的框架设计中,使用的也是这一种模式。服务器端指的就是所有App共用的系统服务,比如我们这里提到的ActivityManagerService,和前面提到的PackageManagerService、WindowManagerService等等,这些基础的系统服务是被所有的App公用的
App和AMS(SystemServer进程)还有zygote进程分属于三个独立的进程,他们之间如何通信呢?
App与AMS通过Binder进行IPC通信,AMS(SystemServer进程)与zygote通过Socket进行IPC通信。
在Android系统中,任何一个Activity的启动都是由AMS和应用程序进程(主要是ActivityThread)相互配合来完成的。AMS服务统一调度系统中所有进程的Activity启动,而每个Activity的启动过程则由其所属的进程具体来完成。
Launcher是什么?什么时候启动的?
当我们点击手机桌面上的图标的时候,App就由Launcher开始启动了。 Launcher本质上也是一个应用程序,和我们的App一样,也是继承自Activity
packages/apps/Launcher2/src/com/android/launcher2/Launcher.java
public final class Launcher extends Activity
implements View.OnClickListener, OnLongClickListener, LauncherModel.Callbacks,
View.OnTouchListener {
}
Launcher实现了点击、长按等回调接口,来接收用户的输入。捕捉图标点击事件,然后startActivity()发送对应的Intent请求。
在桌面上点击快捷图标的时候,会调用
startActivitySafely(v, intent, tag);即
mLauncher.startActivitySafely(v, appInfo.intent, appInfo);
不管从哪里点击图标,调用的都是Launcher.startActivitySafely()。
Instrumentation是什么?和ActivityThread是什么关系?
每个Activity都持有Instrumentation对象的一个引用,但是整个进程只会存在一个Instrumentation对象。当startActivityForResult()调用之后,实际上还是调用了mInstrumentation.execStartActivity()
Instrumentation这个类很重要,对Activity生命周期方法的调用根本就离不开他
App和AMS是通过Binder传递信息的,那么ActivityThread就是专门与AMS的外交工作的。
AMS说:“ActivityThread,你给我暂停一个Activity!” ActivityThread就说:“没问题!”然后转身和Instrumentation说:“老婆,AMS让暂停一个Activity,我这里忙着呢,你快去帮我把这事办了把~” 于是,Instrumentation就去把事儿搞定了。
所以说,AMS是董事会,负责指挥和调度的,ActivityThread是老板,虽然说家里的事自己说了算,但是需要听从AMS的指挥,而Instrumentation则是老板娘,负责家里的大事小事,但是一般不抛头露面,听一家之主ActivityThread的安排。
如何理解AMS和ActivityThread之间的Binder通信
客户端调用ActivityManagerProxy接口里面的方法,把数据传送给Binder驱动,然后Binder驱动就会把这些东西转发给服务器的ActivityManagerServices,由ActivityManagerServices去真正的实施具体的操作。
但是Binder只能传递数据,并不知道是要调用ActivityManagerServices的哪个方法,
客户端:ActivityManagerProxy =====>Binder驱动=====> ActivityManagerService:服务器
而且由于继承了同样的公共接口类,ActivityManagerProxy提供了与ActivityManagerService一样的函数原型,使用户感觉不出Server是运行在本地还是远端,从而可以更加方便的调用这些重要的系统服务。
但是!这里Binder通信是单方向的,即从ActivityManagerProxy指向ActivityManagerService的,如果AMS想要通知ActivityThread做一些事情,应该咋办呢?
还是通过Binder通信,不过是换了另外一对,换成了ApplicationThread和ApplicationThreadProxy。
客户端:ApplicationThread <=====Binder驱动<===== ApplicationThreadProxy:服务器
AMS接收到客户端的请求之后,会如何开启一个Activity?
注意点
- 不要使用 startActivityForResult(intent,RESULT_OK)
而
public static final int RESULT_OK = -1;
所以
startActivityForResult(intent,RESULT_OK) = startActivity()
- 一个App的程序入口到底是什么?
是ActivityThread.main()。
- 整个App的主线程的消息循环是在哪里创建的?
是在ActivityThread初始化的时候,就已经创建消息循环了,所以在主线程里面创建Handler不需要指定Looper,而如果在其他线程使用Handler,则需要单独使用Looper.prepare()和Looper.loop()创建消息循环。
- Application是在什么时候创建的?onCreate()什么时候调用的?
也是在ActivityThread.main()的时候,再具体点呢,就是在thread.attach(false)的时候。
启动流程
- 点击桌面App图标,Launcher进程采用Binder IPC向system_server进程发起startActivity请求;
- system_server进程接收到请求后,向zygote进程发送创建进程的请求;
- Zygote进程fork出新的子进程,即App进程;
- App进程,通过Binder IPC向sytem_server进程发起attachApplication请求;
- system_server进程在收到请求后,进行一系列准备工作后,再通过binder IPC向App进程发送scheduleLaunchActivity请求;
- App进程的binder线程(ApplicationThread)在收到请求后,通过handler向主线程发送LAUNCH_ACTIVITY消息;
- 主线程在收到Message后,通过发射机制创建目标Activity,并回调Activity.onCreate()等方法。