- Android框架层
- Android深入四大组件 categories:
- Android框架层
本文首发于微信公众号「刘望舒」
前言
在几个月前我写了Android深入四大组件(一)应用程序启动过程(前篇)和Android深入四大组件(一)应用程序启动过程(后篇)这两篇文章,它们都是基于Android 7.0,当我开始阅读Android 8.0源码时发现应用程序(根Activity)启动过程照Android 7.0有了一些变化,因此又写下了本篇文章,本篇文章照此前的文章不仅流程发生变化,而且增加了一些分析,算是升级版本。由于篇幅较长,Android8.0 根Activity启动过程仍旧分为前篇和后篇来进行讲解。
<!--more-->1. ActivityThread启动Activity的过程
通过前篇的介绍,我们知道目前的代码逻辑运行在应用程序进程中。先来查看ActivityThread启动Activity的过程的时序图。
我们接着来查看ApplicationThread的scheduleLaunchActivity方法,其中ApplicationThread是ActivityThread的内部类,应用程序进程创建后会运行代表主线程的实例ActivityThread,它管理着当前应用程序进程的线程。ApplicationThread的scheduleLaunchActivity方法如下所示。
frameworks/base/core/java/android/app/ActivityThread.java
1 @Override 2 public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident, 3 ActivityInfo info, Configuration curConfig, Configuration overrideConfig, 4 CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor, 5 int procState, Bundle state, PersistableBundle persistentState, 6 List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents, 7 boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) { 8 updateProcessState(procState, false); 9 ActivityClientRecord r = new ActivityClientRecord(); 10 r.token = token; 11 r.ident = ident; 12 r.intent = intent; 13 r.referrer = referrer; 14 ... 15 updatePendingConfiguration(curConfig); 16 sendMessage(H.LAUNCH_ACTIVITY, r); 17 }
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) { 2 if (DEBUG_MESSAGES) Slog.v( 3 TAG, "SCHEDULE " + what + " " + mH.codeToString(what) 4 + ": " + arg1 + " / " + obj); 5 Message msg = Message.obtain(); 6 msg.what = what; 7 msg.obj = obj; 8 msg.arg1 = arg1; 9 msg.arg2 = arg2; 10 if (async) { 11 msg.setAsynchronous(true); 12 } 13 mH.sendMessage(msg); 14 }
这里mH指的是H,它是ActivityThread的内部类并继承Handler,是应用程序进程中主线程的消息管理类。H的代码如下所示。
1private class H extends Handler { 2 public static final int LAUNCH_ACTIVITY = 100; 3 public static final int PAUSE_ACTIVITY = 101; 4... 5public void handleMessage(Message msg) { 6 if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what)); 7 switch (msg.what) { 8 case LAUNCH_ACTIVITY: { 9 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart"); 10 final ActivityClientRecord r = (ActivityClientRecord) msg.obj;//1 11 r.packageInfo = getPackageInfoNoCheck( 12 r.activityInfo.applicationInfo, r.compatInfo);//2 13 handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");//3 14 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 15 } break; 16 case RELAUNCH_ACTIVITY: { 17 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityRestart"); 18 ActivityClientRecord r = (ActivityClientRecord)msg.obj; 19 handleRelaunchActivity(r); 20 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 21 } break; 22 ... 23}
查看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
1private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) { 2 ... 3 WindowManagerGlobal.initialize(); 4 //启动Activity 5 Activity a = performLaunchActivity(r, customIntent);//1 6 if (a != null) { 7 r.createdConfig = new Configuration(mConfiguration); 8 reportSizeConfigurations(r); 9 Bundle oldState = r.state; 10 //将Activity的状态置为Resume 11 handleResumeActivity(r.token, false, r.isForward, 12 !r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);//2 13 if (!r.activity.mFinished && r.startsNotResumed) { 14 performPauseActivityIfNeeded(r, reason); 15 if (r.isPreHoneycomb()) { 16 r.state = oldState; 17 } 18 } 19 } else { 20 try { 21 //停止Activity启动 22 ActivityManager.getService() 23 .finishActivity(r.token, Activity.RESULT_CANCELED, null, 24 Activity.DONT_FINISH_TASK_WITH_ACTIVITY); 25 } catch (RemoteException ex) { 26 throw ex.rethrowFromSystemServer(); 27 } 28 } 29}
注释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) { 2 //获取ActivityInfo类 3 ActivityInfo aInfo = r.activityInfo;//1 4 if (r.packageInfo == null) { 5 //获取APK文件的描述类LoadedApk 6 r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo, 7 Context.CONTEXT_INCLUDE_CODE);//2 8 } 9 10 ComponentName component = r.intent.getComponent();//3 11 ... 12 //创建要启动Activity的上下文环境 13 ContextImpl appContext = createBaseContextForActivity(r);//4 14 Activity activity = null; 15 try { 16 java.lang.ClassLoader cl = appContext.getClassLoader(); 17 //用类加载器来创建该Activity的实例 18 activity = mInstrumentation.newActivity( 19 cl, component.getClassName(), r.intent);//5 20 ... 21 } catch (Exception e) { 22 ... 23 } 24 25 try { 26 //创建Application 27 Application app = r.packageInfo.makeApplication(false, mInstrumentation);//6 28 ... 29 if (activity != null) { 30 ... 31 /** 32 *7 初始化Activity 33 */ 34 activity.attach(appContext, this, getInstrumentation(), r.token, 35 r.ident, app, r.intent, r.activityInfo, title, r.parent, 36 r.embeddedID, r.lastNonConfigurationInstances, config, 37 r.referrer, r.voiceInteractor, window, r.configCallback); 38 39 ... 40 if (r.isPersistable()) { 41 mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);//8 42 } else { 43 mInstrumentation.callActivityOnCreate(activity, r.state); 44 } 45 ... 46 } 47 r.paused = true; 48 mActivities.put(r.token, r); 49 } catch (SuperNotCalledException e) { 50 throw e; 51 } catch (Exception e) { 52 ... 53 } 54 55 return activity; 56 }
注释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 public void callActivityOnCreate(Activity activity, Bundle icicle, 2 PersistableBundle persistentState) { 3 prePerformCreate(activity); 4 activity.performCreate(icicle, persistentState);//1 5 postPerformCreate(activity); 6 }
注释1处调用了Activity的performCreate方法,代码如下所示。 frameworks/base/core/java/android/app/Activity.java
1 final void performCreate(Bundle icicle, PersistableBundle persistentState) { 2 restoreHasCurrentPermissionRequest(icicle); 3 onCreate(icicle, persistentState); 4 mActivityTransitionState.readState(icicle); 5 performCreateCommon(); 6 }
performCreate方法中会调用Activity的onCreate方法,讲到这里,根Activity就启动了,即应用程序就启动了。 根Activity启动过程就讲到这里,下面我们来学习根Activity启动过程中涉及到的进程。
2. 根Activity启动过程中涉及的进程
在应用程序进程没有创建的情况下,根Activity启动过程中会涉及到4个进程,分别是Zygote进程、Launcher进程、AMS所在进程(SyetemServer进程)、应用程序进程。它们之间的关系如下图所示。

首先Launcher进程向AMS请求创建根Activity,AMS会判断根Activity所需的应用程序进程是否存在并启动,如果不存在就会请求Zygote进程创建应用程序进程。应用程序进程准备就绪后会通知AMS,AMS会请求应用程序进程创建根Activity。上图中步骤2采用的是Socket通信,步骤1和步骤4采用的是Binder通信。 上图可能并不是很直观,为了更好的理解,下面给出这四个进程调用的时序图。

如果是普通Activity启动过程会涉及到几个进程呢?答案是两个,AMS所在进程和应用程序进程。实际上理解了根Activity的启动过程(根Activity的onCreate过程),根Activity和普通Activity其他生命周期状态比如onStart、onResume等过程也会很轻松的掌握,这些知识点都是触类旁通的,想要具体了解这些知识点的同学可以自行阅读源码。
