Android 6.0 Launcher 启动 Activity 过程分析小结(四)

2017-12-22
6 min read

在如下三篇文章中过了一遍 Launcher 启动 Activity 的代码流程。

然而, 即使看过了多遍代码流程依旧有点云里雾里的感觉。不从整体上来把握,光抓住细节代码会始终不得要领。

由于是从 Launcher 组件启动一个 Activity 组件,其中还需要与 ActivityManagerService 通信,而这三个部分都是位于不同的进程内,涉及进程间通信,因此可以将整个过程划分为三个不同的部分来分析,在 Launcher 进程内的操作,在 ActivityManagerService 进程内的操作,在创建的应用程序进程内的操作。

Launcher 进程内的操作

在 Launcher 进程内执行函数:

  • Launcher . startActivitySafely(View v, Intent intent, Object tag)

  • Launcher . startActivity(View v, Intent intent, Object tag)

  • Activity . startActivity(Intent intent, @Nullable Bundle options)

  • Activity . startActivityForResult(Intent intent, int requestCode, @Nullable Bundle options)

  • Instrumentation . execStartActivity( Context who, IBinder contextThread, IBinder token, Activity target, Intent intent, int requestCode, Bundle options)

  • ActivityManagerProxy . startActivity(IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle options)

Launcher 进程这部分执行的操作主要就是 委托ActivityManagerService 去启动一个 Activity 组件,把这个 Activity 组件的 Intent信息传递过去,把自己的包名信息传递过去,还把自己的本地 Binder 对象 ApplicationThread传递过去,以便 ActivityManagerService 可以通过它来联系到 Launcher 组件。

毕竟,当 ActivityManagerService 要去创建新的 Activity 组件时,首先得让之前的 Activity 组件进入 Paused状态。

Launcher 组件的运行流程从startActivitySafelystartActivity,再从 Activity 类的startActivitystartActivityForResult,最后通过 Instrumentation类的execStartActivity方法得到 ActivityManagerService 的代理对象 ActivityManagerProxy来执行startActivity。成功地把 Activity 组件启动的任务交给了 ActivityManagerService 去完成。

ActivityManagerService 进程

在 Launcher 进程内执行函数:

  • ActivityManagerService . startActivity(IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle options)

  • ActivityManagerService . startActivityAsUser(IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId)

  • ActivityStackSupervisor . startActivityMayWait(…)

  • ActivityStackSupervisor . startActivityLocked( …)

  • ActivityStackSupervisor . startActivityUncheckedLocked( …)

  • ActivityStack . startActivityLocked(ActivityRecord r, boolean newTask, boolean doResume, boolean keepCurTransition, Bundle options)

  • ActivityStackSupervisor . resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target, Bundle targetOptions)

  • ActivityStack . resumeTopActivityLocked(ActivityRecord prev, Bundle options)

  • ActivityStack . resumeTopActivityInnerLocked(ActivityRecord prev, Bundle options)

  • ActivityStackSupervisor . startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig)

ActivityManagerService 响应跨进程调用执行startActivity方法,方法内执行startActivityAsUser方法。

接着执行startActivityMayWait方法,首先通过 PackageManager解析待启动 Activity 的 Intent 信息,得到了包含更多信息的 ActivityInfo对象。

接着开始执行startActivityLocked方法,创建一个待启动的 Activity 组件的 ActivityRecord对象,里面包含了相关信息。在接下来的方法startActivityUncheckedLocked中为待启动的 Activity 组件找到它的 Task 任务,由于是新建的 Activity,则直接创建了一个新的 Task。而这个 Task也是 ActivityRecord的成员变量task。由这个 TaskRecord得到它的成员变量ActivityStack ,管理 Activity 的堆栈。

接下来便执行 ActivityStack类的startActivityLocked方法, 首先将待启动的 ActivityRecord 位于栈顶,然后执行 resumeTopActivitiesLocked方法,将所有 ActivityStack 栈顶的 ActivityRecord 运行至 Resumed 状态,其中都是调用的resumeTopActivityLocked方法,而该方法内部又是调用的resumeTopActivityInnerLocked方法,该方法会做一系列的判断,判断当年能够将 ActivityStack 栈顶的 Activity 运行至 Resumed状态,比如:当有 Activity 没有进入 Paused 状态时,便会通过跨进程通信来通知它进入 Paused 状态。当所有的状态都满足了,准备就绪了,就会去检查应用程序进程是否启动了,如果没有则去创建进程,否则让 Activity 组件运行至 Resumed 状态。

ActivityManagerService 创建应用程序进程

  • ActivityStackSupervisor . startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig)

  • ActivityManagerService . startProcessLocked(…)

  • ActivityManagerService . newProcessRecordLocked(ApplicationInfo info, String customProcess, boolean isolated, int isolatedUid)

  • ActivityManagerService . startProcessLocked(…)

startSpecificActivityLocked方法会创建应用程序进程,在 startProcessLocked方法内部根据进程名称和用户 ID 检查应用程序是否存在,不存在,则调用了newProcessRecordLocked方法创建了一个ProcessRecord对象,它包含了进程的基本信息,根据这个 ProcessRecord对象,在startProcessLocked函数的另一形式中去创建了应用程序进程。

当应用程序进程创建成功后,会得到一个大于 0 的进程 ID ,而 ActivityManagerService 就以这个 ID 为关键字将这个进程对应的 ProcessRecord 保存在变量mPidsSelfLocked中,以便 ActivityManagerService 可以根据这个 ID 找到该进程的记录信息。

当进程创建成功后,便会开始运行了,而 Java 程序的入口就是 main函数了。

Activity 应用程序进程启动

  • ActivityThread . main(…)

  • ActivityThread . attach(boolean system)

  • ActivityManagerService . attachApplication(IApplicationThread thread)

  • ActivityManagerService . attachApplicationLocked(IApplicationThread thread, int pid)

  • ApplicationThread . bindApplication(…)

  • ActivityThread . handleBindApplication(AppBindData data)

  • StackSupervisor . attachApplicationLocked(ProcessRecord app)

  • StackSupervisor . realStartActivityLocked(ActivityRecord r, ProcessRecord app, boolean andResume, boolean checkConfig)

  • ApplicationThread . scheduleLaunchActivity(…)

  • ActivityThread . handleLaunchActivity(ActivityClientRecord r, Intent customIntent)

  • ActivityThread . performLaunchActivity(ActivityClientRecord r, Intent customIntent)

  • ActivityThread . handleResumeActivity(IBinder token, boolean clearHide, boolean isForward, boolean reallyResume)

  • ActivityThread . performResumeActivity(IBinder token, boolean clearHide)

由于 Process 类的 start 方法指定了 ActivityThread 类的 main 方法作为一个进程的开始点,跟进 main 方法,初始化线程消息循环,并且在 attach方法中向 ActivityManagerService 跨进程发送请求,要求 ActivityManagerService 将当前进程添加 Application ,毕竟这还是个单纯的进程,并不是 Android 进程。

于是 ActivityManagerService 执行了 attachApplication方法响应这个跨进程请求,接着又继续调用了 attachApplicationLocked方法,从mPidsSelfLocked变量中根据 PID 找到 Activity 应用程序进程对应的 ProcessRecord 。然后将ProcessRecord绑定到应用进程,将ApplicationThread赋值给ProcessRecord的成员变量thread,这样就能 ActivityManagerService 就能通过它来和 Activity 通信了。

接下来 ActivityManagerService 又发起跨进程调用,通过 ApplicationThreadbindApplication方法。ActivityThread 主线程消息循环收到 Handler 发送的消息,响应方法为handleBindApplication。在此方法内,创建了Application 运行环境上下文Context、监控程序与系统交互的Instrumentation、应用程序的Application、并且调用了Application的 onCreate 方法。

当 ActivityManagerService 将 Activity 的 Application 创建完成后,又开始调度 Activity 的生命周期了。通过 StackSupervisor 类的 attachApplicationLocked方法,找到位于栈顶的 ActivityRecord对象,检查这个 Activity 组件的用户 ID 和进程名是否与 ProcessRecord 对象所描述的一致,如果一致,则调用realStartActivityLocked真正的开启一个 Activity 组件了。

开启一个 Activity 组件的生命周期当然是在应用程序进程内了,此时又是 ActivityManagerService 的跨进程通信,执行 ApplicationThread 的 scheduleLaunchActivity,ActivityThread 的消息循环响应方法为 handleLaunchActivity。在该方法内又继续执行 performLaunchActivity将 Activity 组件启动起来。通过反射创建了一个 Activity 对象,并且创建了 Activity 的运行环境上下文,通过 Instrumentation 执行了 Activity 的 onCreate 方法、onStart 方法。接着又执行了handleResumeActivity方法让 Activity 运行到 Resumed状态,真正执行操作的是performResumeActivity方法,而最终还是调用 Instrumentation类的callActivityOnResume方法。

至此,一个 Activity 组件就已经创建成功了,里面具体的代码细节暂不深入讨论了,比如 Activity 的加载之类的。

原创文章,转载请注明来源:    Android 6.0 Launcher 启动 Activity 过程分析小结(四)


欢迎关注微信公众号:音视频开发进阶