App的启动流程

App的启动流程简单来讲包括以下内容:fork进程、启动binder、loop循环、App和AMS双向通信的建立、生命周期回调、App和WMS双向通信的建立。

把这些串起来,是这篇博客的目标。

App的启动流程

只是概要。如果表述太多的细节,一是我写不清楚,容易误导观众;二是太多内容,就不能很好地把握主线流程了。

但是,我会把相关细节的源码地址贴出来,能从中学到什么,就看读者的水平了。

引用的源码是android-10.0.0_r30,不同版本的大致流程基本上是一样的,所以咱们就用最新的吧,顺便学习一下最新的源码。(最开始的时候,我直接把master分支的贴了上来,傻了,大家别犯这样的错。)

https://cs.android.com/http://androidxref.com/用着要方便很多,方法定义、引用、覆盖都很容易定位。引用的链接也可以直接跳转到行。只是,需要科学上网。在我们伟大的祖国做Android开发,这个应该是必备技能了吧!


建议把下面的时序图在另一个浏览器标签打开,对比着文字一起看。

  1. Launcher或其它应用调用startActivity(),最终会通过AMS来启动Activity,因为AMS的主要职责就是管理四大组件的生命周期。

    ActivityManagerService#startActivityAsUser()

    ActivityTaskManagerService#startActivityAsUser()//从Android 10开始google对AMS进行了很大的重构,activity启动、生命周期相应的事情都交给了ActivityTaskManagerService(ATMS)来处理了。

    ActivityStarter#startActivityUnchecked()//处理各种启动模式

    RootActivityContainer#resumeFocusedStacksTopActivities()

    ActivityStack#resumeTopActivityUncheckedLocked()

    ActivityStack#resumeTopActivityInnerLocked()

    ActivityStackSupervisor#startSpecificActivityLocked()//

  2. 假设是冷启动,AMS向zygote发起socket通信:请求创建App进程。

    if (wpc != null && wpc.hasThread())//接上面startSpecificActivityLocked(),判断进程有没有启动

    ActivityManagerService.LocalService#startProcess()//启动进程

    ProcessList#startProcessLocked()//搜一下String entryPoint = "android.app.ActivityThread",App的入口是在这里传给zygote的。

    ZygoteProcess#attemptUsapSendArgsAndGetResult//找到了LocalSocket,把启动参数发给zygote。

  3. zygote在socket loop循环中收到请求,然后fork App进程。

    Android进程的概念对应用层是隐藏的。启动进程的动作是在启动四大组件的时候触发。应用程序的入口不是onCreate()(手动狗头,Android开发的蛮荒时代,不少Android工程师还真是这么认为的),通过源码会发现,和其它java程序一样,App的入口也是所谓的main()方法,即ActivityThread.main()

    ZygoteServer#runSelectLoop//socket循环(接收消息)

    ZygoteConnection#processOneCommand//处理消息

    Zygote#forkAndSpecialize()//fork App进程。fork返回后,父进程和子进程分别进入handleParentProchandleChildProc

    RuntimeInit#findStaticMain//找到ActivityThread的main()方法

  4. App进程创建出来之后,第一件事情就是开启binder机制。

    ZygoteConnection#handleChildProc()//从上面的ZygoteConnection#processOneCommandfork出子进程,进入这里。

    ZygoteInit.zygoteInit//处理App进程的初始化

    AppRuntime#onZygoteInit()//开启binder机制

  5. 接着进入ActivityThreadmain()方法,开启MainLooper,以及下面的向AMS报到初始化完成。这样主线程就以事件驱动的方式,在loop循环里一直运行下去。

    ActivityThread#main()

  6. App进程向AMS报到初始化完成,同时向AMS注册ApplicationThread Binder对象,之后App进程就可以和AMS双向通信。

    ActivityManagerService#attachApplication(appThread)主要做了以下几件事:

    1. removePROC_START_TIMEOUT_MSG消息

      Message msg = mService.mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);//AMS在ActivityManagerService#startProcess()之后,sendMessageDelayed开始监控App进程初始化的执行时间。

      mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);//如果App进程在规定时间内调用attachApplication,表明没有超时,就可以remove消息。

      ActivityManagerService#processStartTimedOutLocked()//否则,执行超时的逻辑,直接清理App进程。

    2. thread.bindApplication()//绑定Application对象。从这里就开始了Application、Activity以及Service的生命周期回调。
    3. 处理pending的任务。源码里的注释写得很清楚了。
      1
      2
      3
      // See if the top visible activity is waiting to run in this process...//继续启动Activity,看下面第8条
      // Find any services that should be running in this process...
      // Check if a next-broadcast receiver is in this process...
  7. 绑定Application对象。

    AMS向App进程的调用都是OneWay的。并且都会由ActivityThread里的class H extends Handler(主线程的一个Handler)来处理。这样的好处就是App进程不会阻塞AMS的执行。

    ActivityThread#handleBindApplication()//反射new Instrumentation(), makeApplication(), installContentProviders(),Application#onCreate()

    Instrumentation//看Instrumentation的注释。了解到Instrumentation的主要作用就是监控system对app的调用

    LoadedApk#makeApplication//反射new Application(), Application#attach()

    ActivityThread#installContentProviders//一些第三方库会利用ContentProvider自动加载来做初始化,比如LeakCanary

    mInstrumentation.callApplicationOnCreate(app);//执行Application#onCreate(),体现了Instrumentation的作用,即上面提到的”监控system对app的调用”,下面还有对Activity分别调用onCreate()、onStart()、onResume()我就不贴出来了,都类似。

  8. 继续启动Activity。

    ActivityTaskManagerService.LocalService#attachApplication()

    RootActivityContainer#attachApplication()//关键看ActivityStack stack = display.getFocusedStack();

    ActivityStackSupervisor#realStartActivityLocked()
    mService.getLifecycleManager().scheduleTransaction(clientTransaction);//构造一个事务ClientTransaction,并设置回调为LaunchActivityItem、生命周期请求为ResumeActivityItem。最终目标是完成Activity的生命周期onCreate()、onStart()、onResume()。

    ClientLifecycleManager#scheduleTransaction()//ClientLifecycleManager是由AMS拆分出的功能,负责生命周期的管理。

    ApplicationThread#scheduleTransaction()//binder调用后,进入App进程

    ClientTransactionHandler#scheduleTransaction
    sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);//执行刚才构造的事务

    case EXECUTE_TRANSACTION://由TransactionExecutor来执行事务

    ActivityThread#handleLaunchActivity()//反射new Activity()、attach()、setTheme(theme)、onCreate()、onStart()

    ActivityThread#handleResumeActivity()//onResume();wm.addView(decor, l);

时序图

更多Android相关时序图,请移步andych008/flow_chart)

右键:新标签页中打开图片 查看大图

笔记

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
ActivityTaskManagerService(ATMS):负责管理activity
ActivityManagerService(AMS):之前版本负责管理activity,与ATMS同一个父类
ActivityTaskManagerInternal:ActivityTaskManagerService对外提供的一个抽象类,真正的实现在ActivityTaskManagerService#LocalService
ActivityStarter:负责启动模式,启动Flag相关处理
ActivityStack:负责管理单独栈activity和其状态,以及具体启动的执行等
ActivityStackSupervisor:与ActivityStack类似,但涉及window相关的操作。Android 10正在重构它。
RootActivityContainer: Android 10新引入,分担ActivityStackSupervisor的部分功能
ClientTransactionItem:事务项,即事务包含的内容。(执行具体activity生命周期的抽象类,子类:LaunchActivityItem等)
ClientTransaction: 事务类(处理相关的信息和生命周期状态)
ClientLifecycleManager: 负责事务的调度,事务包括:多个回调和一个生命周期请求。

TransactionExecutor: 负责执行ClientTransaction
ClientTransactionHandler: 负责ClientTransactionItem回调的执行,ActivityThread是其实现类。

参考链接:https://juejin.im/post/5dda8504e51d452306073434