Android-Activity启动流程
http://www.jianshu.com/p/6037f6fda285
zygote是什么?有什么作用?
zygote意为“受精卵“。
在Android系统里面,zygote是一个进程的名字。Android是基于Linux System的,当你的手机开机的时候,Linux的内核加载完成之后就会启动一个叫“init“的进程。在Linux System里面,所有的进程都是由init进程fork出来的,我们的zygote进程也不例外。
所以当系统里面的第一个zygote进程运行之后,在这之后再开启App,就相当于开启一个新的进程。而为了实现资源共用和更快的启动速度,Android系统开启新进程的方式,是通过fork第一个zygote进程实现的。所以说,除了第一个zygote进程,其他应用所在的进程都是zygote的子进程,这下你明白为什么这个进程叫“受精卵”了吧?因为就像是一个受精卵一样,它能快速的分裂,并且产生遗传物质一样的细胞!
SystemServer是什么?有什么作用?它与zygote的关系是什么?
SystemServer也是一个进程,而且是由zygote进程fork出来的。
系统里面重要的服务都是在这个进程里面开启的,比如
ActivityManagerService、PackageManagerService、WindowManagerService等等
public final class SystemServer { //zygote的主入口 public static void main(String[] args) { new SystemServer().run(); } public SystemServer() { // Check for factory test mode. mFactoryTestMode = FactoryTest.getMode(); } private void run() { ...ignore some code... //加载本地系统服务库,并进行初始化 System.loadLibrary("android_servers"); nativeInit(); // 创建系统上下文 createSystemContext(); //初始化SystemServiceManager对象,下面的系统服务开启都需要调用SystemServiceManager.startService(Class<T>),这个方法通过反射来启动对应的服务 mSystemServiceManager = new SystemServiceManager(mSystemContext); //开启服务 try { startBootstrapServices(); startCoreServices(); startOtherServices(); } catch (Throwable ex) { Slog.e("System", "******************************************"); Slog.e("System", "************ Failure starting system services", ex); throw ex; } ...ignore some code... } //初始化系统上下文对象mSystemContext,并设置默认的主题,mSystemContext实际上是一个ContextImpl对象。调用ActivityThread.systemMain()的时候,会调用ActivityThread.attach(true),而在attach()里面,则创建了Application对象,并调用了Application.onCreate()。 private void createSystemContext() { ActivityThread activityThread = ActivityThread.systemMain(); mSystemContext = activityThread.getSystemContext(); mSystemContext.setTheme(android.R.style.Theme_DeviceDefault_Light_DarkActionBar); } //在这里开启了几个核心的服务,因为这些服务之间相互依赖,所以都放在了这个方法里面。 private void startBootstrapServices() { ...ignore some code... //初始化ActivityManagerService mActivityManagerService = mSystemServiceManager.startService( ActivityManagerService.Lifecycle.class).getService(); mActivityManagerService.setSystemServiceManager(mSystemServiceManager); //初始化PowerManagerService,因为其他服务需要依赖这个Service,因此需要尽快的初始化 mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class); // 现在电源管理已经开启,ActivityManagerService负责电源管理功能 mActivityManagerService.initPowerManagement(); // 初始化DisplayManagerService mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class); //初始化PackageManagerService mPackageManagerService = PackageManagerService.main(mSystemContext, mInstaller, mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore); ...ignore some code... } }
这段代码很重要。
看完下面的你就知道为什么了。
ActivityManagerService是什么?什么时候初始化的?有什么作用?
ActivityManagerService,简称AMS,服务端对象,负责系统中所有Activity的生命周期。
ActivityManagerService进行初始化的时机很明确,就是在SystemServer进程开启的时候,就会初始化ActivityManagerService。
而且在这之前,调用createSystemContext()创建系统上下文的时候,也已经完成了mSystemContext和ActivityThread的创建。注意,这是系统进程开启时的流程,在这之后,会开启系统的Launcher程序,完成系统界面的加载与显示。
那么AMS有什么用呢?在前面我们知道了,如果想打开一个App的话,需要AMS去通知zygote进程,除此之外,其实所有的Activity的开启、暂停、关闭都需要AMS来控制,所以我们说,AMS负责系统中所有Activity的生命周期。
Launcher是什么?什么时候启动的?
当我们点击手机桌面上的图标的时候,App就由Launcher开始启动了。Launcher本质上也是一个应用程序。
当我们点击一个图标时,最终其实就是
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent, opts.toBundle());
所以我们现在明确了,Launcher中开启一个App,其实和我们在Activity中直接startActivity()基本一样,都是调用了Activity.startActivityForResult()。
Instrumentation是什么?和ActivityThread是什么关系?
还记得前面说过的Instrumentation对象吗?每个Activity都持有Instrumentation对象的一个引用,但是整个进程只会存在一个Instrumentation对象。当startActivityForResult()调用之后,实际上还是调用了mInstrumentation.execStartActivity()
Instrumentation意为“仪器”,这个类就是完成对Application和Activity初始化和生命周期的工具类。
AMS是董事会,负责指挥和调度的,ActivityThread是老板,虽然说家里的事自己说了算,但是需要听从AMS的指挥,而Instrumentation则是老板娘,负责家里的大事小事,但是一般不抛头露面,听一家之主ActivityThread的安排。
如何理解AMS和ActivityThread之间的Binder通信?
AMS和ActivityThread之间是用Binder通信的。很明显AMS是服务器端,而AT是客户端。
public abstract class ActivityManagerNative extends Binder implements IActivityManager { //从类声明上,我们可以看到ActivityManagerNative是Binder的一个子类,而且实现了IActivityManager接口 static public IActivityManager getDefault() { return gDefault.get(); } //通过单例模式获取一个IActivityManager对象,这个对象通过asInterface(b)获得 private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() { protected IActivityManager create() { IBinder b = ServiceManager.getService("activity"); if (false) { Log.v("ActivityManager", "default service binder = " + b); } IActivityManager am = asInterface(b); if (false) { Log.v("ActivityManager", "default service = " + am); } return am; } }; } //最终返回的还是一个ActivityManagerProxy对象 static public IActivityManager asInterface(IBinder obj) { if (obj == null) { return null; } IActivityManager in = (IActivityManager)obj.queryLocalInterface(descriptor); if (in != null) { return in; } //这里面的Binder类型的obj参数会作为ActivityManagerProxy的成员变量保存为mRemote成员变量,负责进行IPC通信 return new ActivityManagerProxy(obj); } }
AMS的Binder对象就是ActivityManagerNative,而IActivityManager是一个IInterface,它代表远程Service具有什么能力。ActivityManagerProxy就是AMS的远程接口。
客户端:ActivityManagerProxy =====>Binder驱动=====> ActivityManagerService:服务器
但是!这里Binder通信是单方向的,即从ActivityManagerProxy指向ActivityManagerService的,如果AMS想要通知ActivityThread做一些事情,应该咋办呢?
还是通过Binder通信,不过是换了另外一对,换成了ApplicationThread和ApplicationThreadProxy。他们也都实现了相同的接口IApplicationThread
客户端:ApplicationThread <=====Binder驱动<===== ApplicationThreadProxy:服务器
AMS接收到客户端的请求之后,会如何开启一个Activity?
至此,点击桌面图标调用startActivity(),终于把数据和要开启Activity的请求发送到了AMS了。
AMS的startActivity最终会调用到ActivityStack的startActivityLocked(ActivityRecord r, boolean newTask,boolean doResume, boolean keepCurTransition, Bundle options)
ActivityRecord代表的就是要开启的Activity对象,里面分装了很多信息,比如所在的ActivityTask等,如果这是首次打开应用,那么这个Activity会被放到ActivityTask的栈顶
送给你们的彩蛋
不要使用 startActivityForResult(intent,RESULT_OK)
这是因为startActivity()是这样实现的
public void startActivity(Intent intent, @Nullable Bundle options) { if (options != null) { startActivityForResult(intent, -1, options); } else { // Note we want to go through this call for compatibility with // applications that may have overridden the method. startActivityForResult(intent, -1); } }
public static final int RESULT_OK = -1;
所以
startActivityForResult(intent,RESULT_OK) = startActivity()
你不可能从onActivityResult()里面收到任何回调。
一个App的程序入口到底是什么?
是ActivityThread.main()。
整个App的主线程的消息循环是在哪里创建的?
是在ActivityThread初始化的时候,就已经创建消息循环了,所以在主线程里面创建Handler不需要指定Looper,而如果在其他线程使用Handler,则需要单独使用Looper.prepare()和Looper.loop()创建消息循环。
Application是在什么时候创建的?onCreate()什么时候调用的?
也是在ActivityThread.main()的时候,再具体点呢,就是在thread.attach(false)的时候。
参考文章
下面的这些文章都是这方面比较精品的,希望你抽出时间研究,这可能需要花费很长时间,但是如果你想进阶为中高级开发者,这一步是必须的。
再次感谢下面这些文章的作者的分享精神。
Binder
zygote
ActivityThread、Instrumentation、AMS
- Android Activity.startActivity流程简介
- Android应用程序进程启动过程的源代码分析
- 框架层理解Activity生命周期(APP启动过程)
- Android应用程序窗口设计框架介绍
- ActivityManagerService分析一:AMS的启动
- Android应用程序窗口设计框架介绍
Launcher