activity的启动流程
activity的启动过程分为两种,一种是根Activity的启动过程,另一种是普通Activity的启动过程。根activity的启动过程更复杂,也更具代表性,所以这里先分析根activity的启动过程。根activity的启动分为三部分:Launcher启请求AMS(ActivityManagerService)过程、AMS到ApplicationThread的调用过程以及ActivityThread启动Activity的过程。可以在这个网站在线看9.0.0_r3源码。
1,Launcher请求AMS过程
Launcher启动后会显示应用的图标于桌面上,这些应用图标就是启动根activity的入口,点击它们时就会通过Launcher类来请求AMS来启动该应用程序。Launcher的源码路径为:/packages/apps/Launcher3/src/com/android/launcher3/Launcher.java
时序图如下:
2,接下来查看ApplicationThread的scheduleLaunchActivity方法,其中ApplicationThread是ActivityThread的内部类,应用程序进程创建后会运行代表主线程的实例ActivityThread,它管理着当前应用程序进程的线程。ApplicationThread的scheduleLaunchActivity方法如下所示。
1 | @Override |
scheduleLaunchActivity方法会将启动Activity的参数封装成ActivityClientRecord ,sendMessage方法向H类发送类型为LAUNCH_ACTIVITY的消息,并将ActivityClientRecord 传递过去,sendMessage方法有多个重载方法,最终调用的sendMessage方法如下所示。
frameworks/base/core/java/android/app/ActivityThread.java:
1 | private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) { |
这里mH指的是H,它是ActivityThread的内部类并继承Handler,是应用程序进程中主线程的消息管理类。H的代码如下所示。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19public void handleMessage(Message msg) {
if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
switch (msg.what) {
case LAUNCH_ACTIVITY: {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
final ActivityClientRecord r = (ActivityClientRecord) msg.obj;//1
r.packageInfo = getPackageInfoNoCheck(
r.activityInfo.applicationInfo, r.compatInfo);//2
handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");//3
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
} break;
case RELAUNCH_ACTIVITY: {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityRestart");
ActivityClientRecord r = (ActivityClientRecord)msg.obj;
handleRelaunchActivity(r);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
} break;
...
}
查看H的handleMessage方法中对LAUNCH_ACTIVITY的处理,在注释1处将传过来的msg的成员变量obj转换为ActivityClientRecord。
在注释2处通过getPackageInfoNoCheck方法获得LoadedApk类型的对象并赋值给ActivityClientRecord 的成员变量packageInfo 。应用程序进程要启动Activity时需要将该Activity所属的APK加载进来,而LoadedApk就是用来描述已加载的APK文件。
在注释3处调用handleLaunchActivity方法,代码如下所示。
frameworks/base/core/java/android/app/ActivityThread.java
1 | private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) { |
注释1处的performLaunchActivity方法用来启动Activity ,注释2处的代码用来将Activity 的状态置为Resume。如果该Activity为null则会通知AMS停止启动Activity。来查看performLaunchActivity方法做了什么:
frameworks/base/core/java/android/app/ActivityThread.java
1 | private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) { |
注释1处用来获取ActivityInfo,ActivityInfo用于存储代码和AndroidManifes设置的Activity和receiver节点信息,比如Activity的theme和launchMode。在注释2处获取APK文件的描述类LoadedApk。注释3处获取要启动的Activity的ComponentName类,ComponentName类中保存了该Activity的包名和类名。注释4处用来创建要启动Activity的上下文环境。注释5处根据ComponentName中存储的Activity类名,用类加载器来创建该Activity的实例。注释6处用来创建Application,makeApplication方法内部会调用Application的onCreate方法。注释7处调用Activity的attach方法初始化Activity,attach方法中会创建Window对象(PhoneWindow)并与Activity自身进行关联。注释8处会调用Instrumentation的callActivityOnCreate方法来启动Activity,如下所示。
frameworks/base/core/java/android/app/Instrumentation.java
1 | final void performCreate(Bundle icicle, PersistableBundle persistentState) { |
performCreate方法中会调用Activity的onCreate方法,讲到这里,根Activity就启动了,即应用程序就启动了。
根Activity启动过程就讲到这里,下面我们来学习根Activity启动过程中涉及到的进程。