android应用启动过程
android 应用启动过程
首先,手机中的主页面、以及显示各个应用图标的页面本身就是一个 Activity
android 应用启动就是我们点击应用图标后的过程
以下以 API28 为例
应用启动涉及 L:三个进程、六个大类
三个进程:
Launcher 进程:整个 App 启动流程的起点,负责接收用户点击屏幕事件,它其实就是一个 Activity,里面实现了点击事件,长按事件,触摸等事件,可以这么理解,把 Launcher 想象成一个总的 Activity,屏幕上各种 App 的 Icon 就是这个 Activity 的 button,当点击 Icon 时,会从 Launcher 跳转到其他页面。
SystemServer 进程:这个进程在整个的 Android 进程中是非常重要的一个,地位和 Zygote 等同,它是属于 Application Framework 层的,Android 中的所有服务,例如 AMS, WindowsManager, PackageManagerService 等等都是由这个 SystemServer fork 出来的。
App 进程:你要启动的 App 所运行的进程。
六个大类:
ActivityManagerService:(AMS)AMS 是 Android 中最核心的服务之一,主要负责系统中四大组件的启动、切换、调度及应用进程的管理和调度等工作,其职责与操作系统中的进程管理和调度模块相类似,因此它在 Android 中非常重要,它本身也是一个 Binder 的实现类。
Instrumentation:监控应用程序和系统的交互。
ActivityThread:应用的入口类,通过调用 main 方法,开启消息循环队列。ActivityThread 所在的线程被称为主线程。
ApplicationThread:ApplicationThread 提供 Binder 通讯接口,AMS 则通过代理调用此 App 进程的本地方法。
ActivityManagerProxy:AMS 服务在当前进程的代理类,负责与 AMS 通信。
ApplicationThreadProxy:ApplicationThread 在 AMS 服务中的代理类,负责与 ApplicationThread 通信。
可以说,启动的流程就是通过这六个大类在这三个进程之间不断通信的过程。
LauncherActivity
package android.app;
LauncherActivity 既是显示所有应用图标的系统页面
LauncherActivity 布局是一个 ListView
listView 的数据集就是 所有应用的数据集合,每个应用信息为 ListItem
ListItem
1 | public static class ListItem { |
而 ListView 涉及的所有信息信息是在 Adapter 的构造函数中获取的,
也就是说其实在启动 LauncherActivity 时,已经获取到所有应用信息
接下来查看 Item 的点击事件,即启动应用的逻辑。
1 | @Override |
此时就会进入到 Activity 的 startActivity,最后会进入 Activity 的下列方法中:
requestCode: -1 options: null
是在系统页面开启另一个应用,所以 mParent = null
1 | public void startActivityForResult(@RequiresPermission Intent intent, int requestCode, |
此时会进入 Instrumentation.java 中的 execStartActivity 函数(7 个参数的)
然后又会调用到
1 | int result = ActivityManager.getService() |
又会调用到 ActivityManagerService 中的 startActivity
然后会调用到 ActivityManagerService 中的 startActivityAsUser
1 | public final int startActivityAsUser(IApplicationThread caller, String callingPackage, |
此处使用构建者模式,execute 执行的是 ActivityStarter.java 中的 execute 函数
而最终会调用到 1193 行的 startActivity
1 | private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord, |
会执行 ActivityStackSupervisor 中的 resumeFocusedStackTopActivityLocked
1 | boolean resumeFocusedStackTopActivityLocked( |
然后又会执行到 ActivityStack 中的 resumeTopActivityUncheckedLocked
1 | boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) { |
又会回到 ActivityStackSupervisor 中的 startSpecificActivityLocked 函数
1 | void startSpecificActivityLocked(ActivityRecord r, |
此时会通过 AMS 获取进程信息,判断进程是否存在,
应用进程存在时会调用 realStartActivityLocked
应用进程不存在时会调用 AMS 中的 startProcessLocked 去开启新进程
暂时先看 应用进程不存在的情景:
AMS startProcessLocked
1 | "this") ( |
然后会调用 Process 中 start 去开启进程
同时注意,此处会判断进程类型, webview
1 | public static final ProcessStartResult start(final String processClass, |
然后又会调用到 ZygoteStartFailedEx 中的 start
1 | public final Process.ProcessStartResult start(final String processClass, |
最终执行 zygoteSendArgsAndGetResult 函数来完成进程的创建。
注意:
Android 中有一个重要的进程 Zygote,翻译为受精卵进程,所有的应用程序进程都是通过 Zygote 进程 fork 得来的。
简单来说就是通过 Binder 请求 AMS 进程,然后 AMS 再发送 Socket 消息给 Zygote 进程,最后统一由 Zygote 进程 fork 出应用进程。
当进程创建完成后,会执行 ActivityThread 中的 main 方法
在 ActivityThread 中就会启动 消息分发 、 Application 的创建、Activity 的创建