美文网首页android高级
Android应用启动流程分析

Android应用启动流程分析

作者: 帝王鲨kingcp | 来源:发表于2018-07-27 17:14 被阅读0次

关键类说明

整个启动流程因为会涉及到多次Binder通信,这里先简要说明一下几个类的用途,方便大家理解整个交互流程:

  • ActivityManagerService :AMS是Android中最核心的服务之一,主要负责系统中四大组件的启动、切换、调度及应用进程的管理和调度等工作,其职责与操作系统中的进程管理和调度模块相类似,因此它在Android中非常重要,它本身也是一个Binder的实现类。
  • Instrumentation :顾名思义,它用来监控应用程序和系统的交互。
  • ActivityThread :应用的入口类,系统通过调用main函数,开启消息循环队列。ActivityThread所在线程被称为应用的主线程(UI线程)。
  • ApplicationThread :ApplicationThread提供Binder通讯接口,AMS则通过代理调用此App进程的本地方法。
  • ActivityManagerProxy :AMS服务在当前进程的代理类,负责与AMS通信。
  • ApplicationThreadProxy :ApplicationThread在AMS服务中的代理类,负责与ApplicationThread通信。

流程分析

1、Launcher响应用户点击,通知AMS

Launcher做为应用的入口,通过starActicity辗转调用到Activity:startActivityForResult而后则调用至Instrumentation:execStartActivity。在Instrumentation:execStartActivity方法中,这里的 ActivityManagerNative.getDefault 返回ActivityManagerService的远程接口,即 ActivityManagerProxy 接口,通过Binder驱动程序, ActivityManagerProxy 与AMS服务通信,则实现了跨进程到System进程。

2、AMS响应Launcher进程请求

从上面的流程我们知道,此时AMS应该处理Launcher进程发来的请求,请参看时序图及源码,此时我们调用到ActivityStackSupervisor:startActivityUncheckedLocked方法。在这个方法中函数经过intent的标志值设置,通过findTaskLocked函数来查找存不存这样的Task,这里返回的结果是null,即intentActivity为null,因此,需要创建一个新的Task来启动这个Activity。现在处理堆栈顶端的Activity是Launcher,与我们即将要启动的MainActivity不是同一个Activity,创建了一个新的Task里面来启动这个Activity。经过栈顶检测,则需要将Launcher推入Paused状态,才可以启动新的Activity。后续则调用至ActivityStack:startPausingLocked,在这个函数中的prev.app.thread是一个ApplicationThread对象的远程接口,通过调用这个远程接口的schedulePauseActivity来通知Launcher进入Paused状态。至此,AMS对Launcher的请求已经响应,这是我们发现又通过Binder通信回调至Launcher进程。

3、Launcher进程挂起Launcher,再次通知AMS

这个流程相对会简单一些,我们来看Launcher中的ActivityThread,这部分Launcher的ActivityThread处理页面Paused并且再次通过ActivityManagerProxy通知AMS。

4、AMS创建新的进程

创建新进程的时候,AMS会保存一个ProcessRecord信息,如果应用程序中的AndroidManifest.xml配置文件中,我们没有指定Application标签的process属性,系统就会默认使用package的名称。每一个应用程序都有自己的uid,因此,这里uid + process的组合就可以为每一个应用程序创建一个ProcessRecord。这里主要是调用Process:start接口来创建一个新的进程,新的进程会导入android.app.ActivityThread类,并且执行它的main函数,这就是每一个应用程序都有一个ActivityThread实例来对应的原因。

5、应用进程初始化

我们来看Activity的main函数,这里绑定了主线程的Looper,并进入消息循环,大家应该知道,整个Android系统是消息驱动的,这也是为什么主线程默认绑定Looper的原因。attach函数最终调用了ActivityManagerService的远程接口ActivityManagerProxy的attachApplication函数,传入的参数是mAppThread,这是一个ApplicationThread类型的Binder对象,它的作用是AMS与应用进程进行进程间通信的。

6、在AMS中注册应用进程,启动启动栈顶页面

前面我们提到了AMS负责系统中四大组件的启动、切换、调度及应用进程的管理和调度等工作,通过上一个流程我们知道应用进程创建后通过Binder驱动与AMS产生交互,此时AMS则将应用进程创建后的信息进行了一次 注册 ,如果拿Windows系统程序注册到的注册表来理解这个过程,可能会更形象一些。mMainStack.topRunningActivityLocked(null)从堆栈顶端取出要启动的Activity,并在realStartActivityLockedhan函数中通过ApplicationThreadProxy调回App进程启动页面。此时在App进程,我们可以看到,经过一些列的调用链最终调用至MainActivity:onCreate函数,之后会调用至onResume,而后会通知AMS该MainActivity已经处于resume状态。至此,整个启动流程告一段落。

应用启动流程时序图.png
详细的启动流程分析

以被启动应用的角度看整个流程

详细分析(个人感觉没有时序来的容易理解)

以应用启动的角度看整个过程.jpg

补充知识 APP启动方式

通常来说,APP中启动方式分为两种:冷启动和热启动。
  • 冷启动:当启动应用时,后台没有该应用的进程,这时系统会重新创建一个新的进程分配给该应用,这个启动方式就是冷启动。
  • 热启动:当启动应用时,后台已有该应用的进程(例:按back键/home键,应用虽然会退出,但是该应用的进程是依然会保留在后台,可进入任务列表查看),所以在已有进程的情况下,这种启动会从已有的进程中来启动应用,这个方式叫热启动。

请注意:上面说的启动是点击app的启动图标来启动的,而另外一种方式是进入最近使用的列表界面来启动应用,这种不应该叫启动,应该叫恢复。

相关文章

网友评论

    本文标题:Android应用启动流程分析

    本文链接:https://www.haomeiwen.com/subject/odxgmftx.html