前言
接触过Android开发的同学都知道Activity,Activity作为Android四大组件之一,使用频率高。简单来说Activity提供了一个显示界面,让用户进行各种操作,本文主要分为以下三个部分:Activity的生命周期,启动模式,以及Activity的工作过程。文中大部分篇幅来自《Android开发艺术探索》一书,尽管想多以流程或图片的形式说明,奈何文笔有限,Android系统整体把握还不够深入,只能借鉴参考前辈的成果,本文主要目的是帮自己梳理Activity的相关问题,疏漏之处欢迎指出。
说明:本文中的源码都是基于Android-25版本。
Activity生命周期
生命周期
首先给出Activity的完整生命周期,如下图所示:

Activity生命周期
图片来源Android开发者官网
看完了完整的生命周期,我们再分别简单介绍单个生命周期含义。
onCreate:表示Activity正在被创建,做一些初始化工作,如加载布局文件,对一些变量或者控件进行初始化onStart:表示Activity正在启动,此时Activity已经可见了,但还无法和用户交互onResume:表示Activity已经在前台,可以和用户交互了onPause:表示Activity正在停止,此时可以进行一些轻量级的存储数据和停止动画等工作,但不能太耗时,否则会影响到新Activity的显示,Android指定如果onPause在500ms内没有执行完毕的话就会强制关闭Activity。某些极端情况下,这个时候Activity会回到当前Activity,此时onResume会被执行,很难重现这一情形onStop:表示Activity即将停止,此时Activity已经不可见了,但是Activity对象还存在内存中,没有被销毁,这个阶段也主要做一些资源回收的工作,不能太耗时onDestory:表示Activity即将被销毁,可以做一些回收工作和最终的资源释放,最后一个回调方法onRestart:表示Activity重新启动,当前Activity从不可见重新变为可见时会调用onRestart,这种情况一般是用户的行为导致的,比如:用户按Home键切换到桌面或者打开了一个新的Activity
三个问题
onCreate,onStart和onResume之间的区别?
onCreate时Activity还不可见,onStart已经可见,还不在前台,onResume已经出现在前台onCreate方法只在Activity创建时执行一次,而onStart方法在Activity的切换以及按Home键返回桌面再切回应用的过程中被多次调用,因此数据恢复在onStart方法中比较合适,onResume方法可以做一些开启动画和独占设备的操作
onPause,onStop和onDestroy之间的区别?
onPause时Activity还可见,onStop已经不可见,但Activity对象还存在内存中,onDestroy后Activity对象就不存在了- 内存不足时,可能不会执行
onStop方法,因此程序状态保存,停止动画,存储数据等操作最好放在onPause中
切换Activity时生命周期执行顺序
假设当前Activity为A,此时用户打开Activity B,那么A和B的生命周期的执行顺序为:

Activity跳转生命周期.png
为了验证生命周期执行顺序,我们写个例子实测,MainActivity中单击按钮跳转到SecondActivity,然后在相应的生命周期中输出日志,如下:
1public class MainActivity extends Activity { 2 3 private static final String TAG = "MainActivity"; 4 5 ... 6 7 @Override 8 protected void onPause(){ 9 super.onPause(); 10 Log.d(TAG,"onPause"); 11 } 12 13 @Override 14 protected void onStop(){ 15 super.onStop(); 16 Log.d(TAG,"onStop"); 17 } 18} 19 20public class SecondActivity extends Activity { 21 22 private static final String TAG = "SecondActivity"; 23 24 @Override 25 protected void onCreate(Bundle savedInstanceState) { 26 super.onCreate(savedInstanceState); 27 setContentView(R.layout.activity_main); 28 Log.d(TAG,"onCreate"); 29 } 30 31 @Override 32 protected void onStart(){ 33 super.onStart(); 34 Log.d(TAG,"onStart"); 35 } 36 37 @Override 38 protected void onResume(){ 39 super.onResume(); 40 Log.d(TAG,"onResume"); 41 } 42}
日志结果如下:
108-31 12:36:36.086 3825-3825/com.sht.user.activityjumptest D/MainActivity: onPause 208-31 12:36:36.093 3825-3825/com.sht.user.activityjumptest D/SecondActivity: onCreate 308-31 12:36:36.093 3825-3825/com.sht.user.activityjumptest D/SecondActivity: onStart 408-31 12:36:36.094 3825-3825/com.sht.user.activityjumptest D/SecondActivity: onResume 508-31 12:36:36.517 3825-3825/com.sht.user.activityjumptest D/MainActivity: onStop
那么为什么会有这样的生命周期执行顺序呢?Android官方文档对onPause的解释为:不能在onPause中做重量级的操作,因为必须onPause执行完成以后新Activity才能Resume,同时我在分析Activity启动源过程中码也得到了相同结论。
Activity保存状态
当 Activity 暂停或停止时,Activity 的状态会得到保留。因为当 Activity 暂停或停止时,Activity 对象仍保留在内存中 ,有关其成员和当前状态的所有信息仍处于活动状态。
但是当系统的配置发生变化(屏幕旋转,语言变换等)时,Activity 被销毁,系统回调 onSaveInstanceState() 方法对有关 Activity 状态的信息进行保存,系统会向该方法传递一个 Bundle,可以在其中使用 putString() 和 putInt() 等方法以名称-值对形式保存有关 Activity 状态的信息。当 Activity 重建时将 Bundle 同时传递给 onCreate() 和 onRestoreInstanceState() 方法,使用上述任一方法从 Bundle 提取保存的数据并恢复该 Activity 状态。

Activity保存状态
图片来源Android开发者官网
在 onSaveInstanceState() 和 onRestoreInstanceState() 方法中,系统自动为我们做了一定的恢复工作,布局中的每个 View 调用自己的 onSaveInstanceState() 方法,让每个视图都能保存自身需保存的信息。
每个 View 都有 onSaveInstanceState() 和 onRestoreInstanceState() 方法,具体能恢复哪些数据,需要查看其源码。保存和恢复 View 用到了事件委托思想,从下至上,再从上到下。需要注意的是,只有我们为 View 指定了唯一的ID属性(android:id)系统才会自动为其在需要时自动保存和恢复数据。
通过重写onSaveInstanceState() 和 onRestoreInstanceState() 实现自定义的数据恢复机制。
那么 onSaveInstanceState() 和 onRestoreInstanceState() 方法和 Activity 的生命周期的执行顺序是怎么样的?
onSaveInstanceState() 方法是在onStop之前,和onPause没有既定的时序关系, onRestoreInstanceState() 方法是在onStart之后、onResume之前调用的。
Activity启动模式
默认情况下,当我们多次启动同一个Activity时,系统会创建多个实例并把它们一一放入任务栈中,任务栈是一种后进先出的栈结构,每按下back键就会有一个Activity出栈,直到栈空为止。
standard:标准模式
这是系统默认的模式,每次启动一个新的Activity都会重新创建一个新的实例,不管这个实例已经是否存在。这种模式下,如果A启动了B(标准模式),那么B自动进入A所在的任务栈中。
singleTop:栈顶复用模式
此种模式下,如果新Activity已经位于任务栈的栈顶,那么此Activity不会被重新创建,同时onNewIntent方法会被调用,通过此方法的参数获取当前请求信息。而且,此Activity的onCreate,onStart不会被调用,因为没有发生改变。
singleTask:栈内复用模式
此种模式下,只要Activity在一个栈中存在,那么多次启动此Activity都不会重新创建实例,系统会回调onNewIntent方法。系统会先寻找是否存在A想要的任务栈,如果不存在,就重建一个任务栈,然后创建A的实例放入新任务栈中;如果存在A想要的任务栈,再查看是否有Activity实例存在,有的话就把该实例调到栈顶,如果实例不存在,则创建A的实例放入任务栈中。下面举三种例子说明此种模式运行机制:
- 目前任务栈S1中为ABC,Activity D以
singleTask模式请求启动,其需要的任务栈为S1,那么系统会创建D的实例,将D放入S1中 - 目前任务栈S1中为ABC,Activity D以
singleTask模式请求启动,其需要的任务栈为S2,那么系统会创建任务栈S2,再将D放入S2中 - 目前任务栈S1中为ADBC,Activity D以
singleTask模式请求启动,其需要的任务栈为S1,那么系统不会创建D的实例,将D切换到栈顶并调用其onNewIntent方法,同时栈内所有在D上面的Activity都需要出栈,最终的S1为AD
singleInstance:单实例模式
这是一种加强的singleTask模式,除了具有singleTask模式的所有特性外,具有此种模式的Activity只能单独位于一个任务栈中。比如Activity A以singleInstance模式启动,系统会为其创建一个新的任务栈,然后A独自运行在该任务栈中,后续的请求均不会创建新的Activity。
任务栈
在启动模式中多次提到Activity的任务栈,默认情况下,所有Activity所需任务栈的名字为应用的包名。此外还有一个参数TaskAffinity,这个参数标识了Activity所需要的任务栈的名字,TaskAffinity属性主要和singleTask模式或者allowTaskReparenting属性配对使用,具体请参考《Android开发艺术探索》P19和Android任务和返回栈完全解析,细数那些你所不知道的细节。
如何指定Activity启动模式
- 第一种是通过AndroidManifest.xml 指定:
1<activity android:name=".SecondActivity" 2 android:launchMode="singleTask" 3 android:label="@string/app_name"/>
- 第二种是通过在Intent中设置标志位,比如:
1Intent intent = new Intent(); 2intent.setClass(MainActivity.this, SecondActivity.class); 3intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 4startActivity(intent);
Activity启动过程源码分析
聊完了Activity的生命周期及启动模式,最头疼的部分来了,那就是一个Activity究竟是如何启动的呢?以下篇幅结合源码一探究竟,拨开云雾见青天。在显式调用启动Activity时,我们通过以下代码完成:
1Intent intent = new Intent(this, TestActivity.class); 2startActivity(intent);
上述代码便可以启动一个Activity,下面我们便从源头理清Activity的启动流程,当然我们不可能对所有细节描述清楚,需要做的是理清流程,点到为止。
startActivity/startActivityForResult
我们从Activity的startActivity方法开始分析,读源码可知,startActivity方法有好几种重载形式,但最终都调用了startActivityForResult方法,因此我们重点分析startActivityForResult方法:
1public void startActivityForResult(@RequiresPermission Intent intent, int requestCode, @Nullable Bundle options) { 2 if (mParent == null) { 3 options = transferSpringboardActivityOptions(options); 4 Instrumentation.ActivityResult ar = 5 mInstrumentation.execStartActivity( 6 this, mMainThread.getApplicationThread(), mToken, this, 7 intent, requestCode, options); 8 if (ar != null) { 9 mMainThread.sendActivityResult( 10 mToken, mEmbeddedID, requestCode, ar.getResultCode(), 11 ar.getResultData()); 12 } 13 if (requestCode >= 0) { 14 // If this start is requesting a result, we can avoid making 15 // the activity visible until the result is received. Setting 16 // this code during onCreate(Bundle savedInstanceState) or onResume() will keep the 17 // activity hidden during this time, to avoid flickering. 18 // This can only be done when a result is requested because 19 // that guarantees we will get information back when the 20 // activity is finished, no matter what happens to it. 21 mStartedActivity = true; 22 } 23 cancelInputsAndStartExitTransition(options); 24 // TODO Consider clearing/flushing other event sources and events for child windows. 25 } else { 26 if (options != null) { 27 mParent.startActivityFromChild(this, intent, requestCode, options); 28 } else { 29 // Note we want to go through this method for compatibility with 30 // existing applications that may have overridden it. 31 mParent.startActivityFromChild(this, intent, requestCode); 32 } 33 } 34}
Instrumentation
我们主要关注mParent == null这一部分逻辑,首先,mParent是一个Activity对象,表示该Activity是否由父Activity启动,如果该Activity是第一个被启动的,那么就会调用Instrumentation的execStartActivity方法:
1public ActivityResult execStartActivity( 2 Context who, IBinder contextThread, IBinder token, Activity target, 3 Intent intent, int requestCode, Bundle options) { 4 IApplicationThread whoThread = (IApplicationThread) contextThread; 5 Uri referrer = target != null ? target.onProvideReferrer() : null; 6 if (referrer != null) { 7 intent.putExtra(Intent.EXTRA_REFERRER, referrer); 8 } 9 if (mActivityMonitors != null) { 10 synchronized (mSync) { 11 final int N = mActivityMonitors.size(); 12 for (int i=0; i<N; i++) { 13 final ActivityMonitor am = mActivityMonitors.get(i); 14 if (am.match(who, null, intent)) { 15 am.mHits++; 16 if (am.isBlocking()) { 17 return requestCode >= 0 ? am.getResult() : null; 18 } 19 break; 20 } 21 } 22 } 23 } 24 try { 25 intent.migrateExtraStreamToClipData(); 26 intent.prepareToLeaveProcess(who); 27 int result = ActivityManagerNative.getDefault() 28 .startActivity(whoThread, who.getBasePackageName(), intent, 29 intent.resolveTypeIfNeeded(who.getContentResolver()), 30 token, target != null ? target.mEmbeddedID : null, 31 requestCode, 0, null, options); 32 // 检查启动Activity的结果 33 checkStartActivityResult(result, intent); 34 } catch (RemoteException e) { 35 throw new RuntimeException("Failure from system", e); 36 } 37 return null; 38}
Instrumentation是管理Activity的一个工具类,包括创建和启动Activity,Activity的生命周期方法都是由Instrumentation这个类来控制,一个进程中只用一个Instrumentation实例。
execStartActivity是真正启动Activity的操作,下面解释其参数:
- who : 待启动的Activity对象
- mMainThread.getApplicationThread() : ApplicationThread对象,也是Binder对象
- mToken :Binder对象,指向服务端一个ActivityRecord对象
- target :待启动的Activity对象
- intent :启动的intent对象
- requestCode :请求码
- options :参数
AMS
再回到execStartActivity方法体中,其中可以看到真正实现Activity启动的是ActivityManagerNative.getDefault().startActivity方法。下面列出了ActivityManagerNative.getDefault()的源码:
1static public IActivityManager getDefault() { 2 return gDefault.get(); 3} 4 5private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() { 6 protected IActivityManager create() { 7 IBinder b = ServiceManager.getService("activity"); 8 if (false) { 9 Log.v("ActivityManager", "default service binder = " + b); 10 } 11 IActivityManager am = asInterface(b); 12 if (false) { 13 Log.v("ActivityManager", "default service = " + am); 14 } 15 return am; 16 } 17}; 18 19static public IActivityManager asInterface(IBinder obj) { 20 if (obj == null) { 21 return null; 22 } 23 IActivityManager in = 24 (IActivityManager)obj.queryLocalInterface(descriptor); 25 if (in != null) { 26 return in; // 同一进程,返回本地对象stub 27 } 28 return new ActivityManagerProxy(obj); // 跨进程,返回代理对象 29}
其中声明了一个Singleton封装类,类型是IActivityManager,第一次调用它的get方法它会通过create方法来初始化AMS这个Binder对象。其中在asInterface方法中返回了一个IActivityManager类型对象。
ActivityManagerService(AMS)继承自ActivityManagerNative,而ActivityManagerNative继承自Binder并实现了IActivityManager接口,因此AMS是一个Binder,同时也是IActivityManager的具体实现,ActivityManagerNative.getDefault()其实是一个IActivityManager类型的Binder对象,即AMS。我们理一下上面提到的各种类和接口之间的关系:
1public final class ActivityManagerService extends ActivityManagerNative {...} 2 3public abstract class ActivityManagerNative extends Binder implements IActivityManager {...} 4 5public interface IActivityManager extends IInterface {...}
所以Activity的启动过程转移到AMS中,下面分析AMS的startActivity方法:
1public final int startActivity(IApplicationThread caller, String callingPackage, 2 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) { 4 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 5 resultWho, requestCode, startFlags, profilerInfo, bOptions, 6 UserHandle.getCallingUserId()); 7} 8 9public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 10 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 11 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) { 12 enforceNotIsolatedCaller("startActivity"); 13 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 14 userId, false, ALLOW_FULL_ONLY, "startActivity", null); 15 16 // Android7.0 Acitivty启动管理类新增ActivityStarter(原本是ActivityStackSupervisor处理该过程) 17 return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, 18 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 19 profilerInfo, null, null, bOptions, false, userId, null, null); 20}
ActivityStarter
上述代码中mActivityStarter是一个ActivityStarter对象,初始化为:
mActivityStarter = new ActivityStarter(this, mStackSupervisor);
可以看出Activity的启动过程转移到ActivityStarter的startActivityMayWait方法中,startActivityMayWait又调用了startActivityLocked方法:
1final int startActivityMayWait(IApplicationThread caller, int callingUid, 2 String callingPackage, Intent intent, String resolvedType, 3 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, 4 IBinder resultTo, String resultWho, int requestCode, int startFlags, 5 ProfilerInfo profilerInfo, IActivityManager.WaitResult outResult, Configuration config, 6 Bundle bOptions, boolean ignoreTargetSecurity, int userId, 7 IActivityContainer iContainer, TaskRecord inTask) { 8 9 ... 10 11 // 根据Intent中在系统中找到合适的应用的Activity,如果有多个Activity可选择则弹出界面让用户选择 12 ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo); 13 14 ... 15 16 int res = startActivityLocked(caller, intent, ephemeralIntent, resolvedType, 17 aInfo, rInfo, voiceSession, voiceInteractor, 18 resultTo, resultWho, requestCode, callingPid, 19 callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, 20 options, ignoreTargetSecurity, componentSpecified, outRecord, container, 21 inTask); 22 23 ... 24 25 return res; 26 } 27}
startActivityLocked方法又调用startActivityUnchecked方法:
1final int startActivityLocked(IApplicationThread caller, Intent intent, Intent ephemeralIntent, 2 String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo, 3 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, 4 IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid, 5 String callingPackage, int realCallingPid, int realCallingUid, int startFlags, 6 ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified, 7 ActivityRecord[] outActivity, ActivityStackSupervisor.ActivityContainer container, 8 TaskRecord inTask) { 9 int err = ActivityManager.START_SUCCESS; 10 11 ... 12 13 // 创建ActivityRecord对象 14 // ActivityRecord : 在AMS中,用ActivityRecord来作为Activity的记录者,每次启动一个Actvity会有一个对应 15 // 的ActivityRecord对象,表示Activity的一个记录 16 ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage, 17 intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho, 18 requestCode, componentSpecified, voiceSession != null, mSupervisor, container, 19 options, sourceRecord); 20 21 ... 22 23 err = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor, startFlags, 24 true, options, inTask); 25 26 ... 27 28 // 此处Activity对应的Task被移至前台 29 postStartActivityUncheckedProcessing(r, err, stack.mStackId, mSourceRecord, mTargetStack); 30 return err; 31}
startActivityUnchecked调用了ActivityStack的startActivityLocked方法和ActivityStackSupervisor的resumeFocusedStackTopActivityLocked方法:
1private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord, 2 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, 3 int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask) { 4 5 ... 6 7 // ActivityStack的startActivityLocked方法 8 mTargetStack.startActivityLocked(mStartActivity, newTask, mKeepCurTransition, mOptions); 9 10 if (mDoResume) { 11 final ActivityRecord topTaskActivity = mStartActivity.task.topRunningActivityLocked(); 12 if (!mTargetStack.isFocusable() 13 || (topTaskActivity != null && topTaskActivity.mTaskOverlay 14 && mStartActivity != topTaskActivity)) { 15 // If the activity is not focusable, we can't resume it, but still would like to 16 // make sure it becomes visible as it starts (this will also trigger entry 17 // animation). An example of this are PIP activities. 18 // Also, we don't want to resume activities in a task that currently has an overlay 19 // as the starting activity just needs to be in the visible paused state until the 20 // over is removed. 21 } else { 22 // ActivityStackSupervisor的resumeFocusedStackTopActivityLocked方法 23 mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,mOptions); 24 } 25 26 ... 27 } 28 29 ... 30 31}
ActivityStackSupervisor
ActivityStackSupervisor的resumeFocusedStackTopActivityLocked方法如下:
1boolean resumeFocusedStackTopActivityLocked( 2 ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) { 3 if (targetStack != null && isFocusedStack(targetStack)) { 4 // 待启动Activity对应的Task为前台栈时,调用该Task对应ActivityStack的resumeTopActivityUncheckedLocked方法 5 return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions); 6 } 7 final ActivityRecord r = mFocusedStack.topRunningActivityLocked(); 8 if (r == null || r.state != RESUMED) { 9 // 否则只是调用此时前台栈的resumeTopActivityUncheckedLocked方法 10 mFocusedStack.resumeTopActivityUncheckedLocked(null, null); 11 } 12 return false; 13}
ActivityStack
下面进入ActivityStack的resumeTopActivityUncheckedLocked方法:
1boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) { 2 3 ... 4 5 result = resumeTopActivityInnerLocked(prev, options); 6 7 ... 8 9 return result; 10}
紧接着又调用了resumeTopActivityInnerLocked方法:
1private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) { 2 3 ... 4 5 // mResumedActivity指向上一次启动的Activity 6 if (mResumedActivity != null) { 7 8 ... 9 10 // 让上一次的Activity进入pause状态 11 pausing |= startPausingLocked(userLeaving, false, next, dontWaitForPause); 12 } 13 14 if (pausing) { 15 ... 16 if (next.app != null && next.app.thread != null) { 17 // 如果Activity所在App已经启动,则更新Activity所在进程优先级,防止被kill 18 mService.updateLruProcessLocked(next.app, true, null); 19 } 20 ... 21 } 22 23 ... 24 25 if (next.app != null && next.app.thread != null) { 26 ... 27 if (next.newIntents != null) { 28 // 如果Intent不为空,则调用NewIntent传入Intent参数 29 next.app.thread.scheduleNewIntent( 30 next.newIntents, next.appToken, false /* andPause */); 31 ... 32 } 33 34 ... 35 36 // Activity已经启动,重新进入前台 37 next.app.thread.scheduleResumeActivity(next.appToken, next.app.repProcState, 38 mService.isNextTransitionForward(), resumeAnimOptions); 39 ... 40 41 } else { 42 ... 43 // 创建进程,启动Activity,或者已经启动App,启动Activity 44 mStackSupervisor.startSpecificActivityLocked(next, true, true); 45 } 46 ... 47 return true; 48}
resumeTopActivityInnerLocked方法又调用了ActivityStackSupervisor的startSpecificActivityLocked方法:
1void startSpecificActivityLocked(ActivityRecord r, 2 boolean andResume, boolean checkConfig) { 3 // Is this activity's application already running? 4 ProcessRecord app = mService.getProcessRecordLocked(r.processName, 5 r.info.applicationInfo.uid, true); 6 7 r.task.stack.setLaunchTime(r); 8 9 if (app != null && app.thread != null) { 10 try { 11 if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0 12 || !"android".equals(r.info.packageName)) { 13 // Don't add this if it is a platform component that is marked 14 // to run in multiple processes, because this is actually 15 // part of the framework so doesn't make sense to track as a 16 // separate apk in the process. 17 app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode, 18 mService.mProcessStats); 19 } 20 // 目标Activity所在APP已启动 21 realStartActivityLocked(r, app, andResume, checkConfig); 22 return; 23 } catch (RemoteException e) { 24 Slog.w(TAG, "Exception when starting activity " 25 + r.intent.getComponent().flattenToShortString(), e); 26 } 27 28 // If a dead object exception was thrown -- fall through to 29 // restart the application. 30 } 31 32 // 目标Activity所在APP未启动,通过zygote创建应用进程 33 mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0, 34 "activity", r.intent.getComponent(), false, false, true); 35}
startSpecificActivityLocked方法调用了realStartActivityLocked方法:
1final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app, 2 boolean andResume, boolean checkConfig) throws RemoteException { 3 4 ... 5 6 // 目标Activity所在APP已启动,通过此方法启动目标Activity 7 app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken, 8 System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration), 9 new Configuration(task.mOverrideConfig), r.compat, r.launchedFromPackage, 10 task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results, 11 newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo); 12 13 ... 14 15}
上面这段代码中,其中app.thread的类型是IApplicationThread,IApplicationThread的声明如下:
public interface IApplicationThread extends IInterface {...}
IApplicationThread继承了IInterface,所以它是一个Binder类型的接口,IApplicationThread内部包含了大量启动、停止Activity的接口,此外还包含启动和停止服务的接口。
IApplicationThread的实现者就是ActivityThread的内部类ApplicationThread,相关类的继承和实现关系如下所示:
1private class ApplicationThread extends ApplicationThreadNative { ... } 2public abstract class ApplicationThreadNative extends Binder implements IApplicationThread { ... }
说了这么多,分析下来不仅累,还容易被绕晕,画张流程图总结下:

ApplicationThread
绕了一圈,Activity的启动过程还是回到了ApplicationThread中,ApplicationThread通过scheduleLaunchActivity方法启动Activity,源码如下:
1public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident, 2 ActivityInfo info, Configuration curConfig, Configuration overrideConfig, 3 CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor, 4 int procState, Bundle state, PersistableBundle persistentState, 5 List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents, 6 boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) { 7 8 updateProcessState(procState, false); 9 10 ActivityClientRecord r = new ActivityClientRecord(); 11 12 r.token = token; 13 r.ident = ident; 14 r.intent = intent; 15 r.referrer = referrer; 16 r.voiceInteractor = voiceInteractor; 17 r.activityInfo = info; 18 r.compatInfo = compatInfo; 19 r.state = state; 20 r.persistentState = persistentState; 21 22 r.pendingResults = pendingResults; 23 r.pendingIntents = pendingNewIntents; 24 25 r.startsNotResumed = notResumed; 26 r.isForward = isForward; 27 28 r.profilerInfo = profilerInfo; 29 30 r.overrideConfig = overrideConfig; 31 updatePendingConfiguration(curConfig); 32 33 sendMessage(H.LAUNCH_ACTIVITY, r); 34}
其主要实现就是发送一个启动消息交由Handler处理,这个Handler有个特殊的名字叫H(是不是很萌的名字),sendMessage的实现如下:
1private void sendMessage(int what, Object obj, int arg1, int arg2, int seq) { 2 if (DEBUG_MESSAGES) Slog.v( 3 TAG, "SCHEDULE " + mH.codeToString(what) + " arg1=" + arg1 + " arg2=" + arg2 + 4 "seq= " + seq); 5 Message msg = Message.obtain(); 6 msg.what = what; 7 SomeArgs args = SomeArgs.obtain(); 8 args.arg1 = obj; 9 args.argi1 = arg1; 10 args.argi2 = arg2; 11 args.argi3 = seq; 12 msg.obj = args; 13 mH.sendMessage(msg); 14}
H对Activity启动的消息进行处理:
1case LAUNCH_ACTIVITY: { 2 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart"); 3 final ActivityClientRecord r = (ActivityClientRecord) msg.obj; 4 5 r.packageInfo = getPackageInfoNoCheck( 6 r.activityInfo.applicationInfo, r.compatInfo); 7 handleLaunchActivity(r, null, "LAUNCH_ACTIVITY"); 8 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 9} 10break;
ActivityThread
从上面代码可以看出,Activity的启动过程又转到ActivityThread的handleLaunchActivity方法中,其源码如下:
1private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) { 2 ... 3 4 // 此方法中完成Activity生命周期的onCreate和onStart方法 5 Activity a = performLaunchActivity(r, customIntent); 6 7 if (a != null) { 8 r.createdConfig = new Configuration(mConfiguration); 9 reportSizeConfigurations(r); 10 Bundle oldState = r.state; 11 // 此方法中完成Activity生命周期的onResume方法 12 handleResumeActivity(r.token, false, r.isForward, 13 !r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason); 14 15 ... 16 } 17 18 ... 19}
上述代码中的performLaunchActivity方法最终完成了Activity对象的创建和启动过程,performLaunchActivity这个方法主要完成了以下几件事:
摘自Android开发艺术探索
- 从ActivityClientRecord中获取待启动的Activity的组件信息
1ActivityInfo aInfo = r.activityInfo; 2if (r.packageInfo == null) { 3 r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo, 4 Context.CONTEXT_INCLUDE_CODE); 5} 6 7// ComponentName用来定义一个应用程序组件,例如Activity,Service,BroadcastReceiver,ContentProvider 8ComponentName component = r.intent.getComponent(); 9if (component == null) { 10 component = r.intent.resolveActivity( 11 mInitialApplication.getPackageManager()); 12 r.intent.setComponent(component); 13} 14 15if (r.activityInfo.targetActivity != null) { 16 component = new ComponentName(r.activityInfo.packageName, 17 r.activityInfo.targetActivity); 18}
- 通过Instrumentation的newActivity方法使用类加载器创建Activity对象
1Activity activity = null; 2try { 3 java.lang.ClassLoader cl = r.packageInfo.getClassLoader(); 4 // 通过类加载器来创建Activity对象 5 activity = mInstrumentation.newActivity( 6 cl, component.getClassName(), r.intent); 7 StrictMode.incrementExpectedActivityCount(activity.getClass()); 8 r.intent.setExtrasClassLoader(cl); 9 r.intent.prepareToEnterProcess(); 10 if (r.state != null) { 11 r.state.setClassLoader(cl); 12 } 13} catch (Exception e) { 14 if (!mInstrumentation.onException(activity, e)) { 15 throw new RuntimeException( 16 "Unable to instantiate activity " + component 17 + ": " + e.toString(), e); 18 } 19}
- 通过LoadedApk的makeApplication方法来创建Application对象
1public Application makeApplication(boolean forceDefaultAppClass, 2 Instrumentation instrumentation) { 3 // 先判断Application是否为空,如果Application被创建过,就不会再重复创建,一个应用只有一个Application对象 4 if (mApplication != null) { 5 return mApplication; 6 } 7 8 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "makeApplication"); 9 10 Application app = null; 11 12 String appClass = mApplicationInfo.className; 13 if (forceDefaultAppClass || (appClass == null)) { 14 appClass = "android.app.Application"; 15 } 16 17 try { 18 java.lang.ClassLoader cl = getClassLoader(); 19 if (!mPackageName.equals("android")) { 20 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, 21 "initializeJavaContextClassLoader"); 22 initializeJavaContextClassLoader(); 23 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 24 } 25 ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this); 26 // 通过类加载器创建Application对象 27 app = mActivityThread.mInstrumentation.newApplication( 28 cl, appClass, appContext); 29 appContext.setOuterContext(app); 30 } catch (Exception e) { 31 if (!mActivityThread.mInstrumentation.onException(app, e)) { 32 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 33 throw new RuntimeException( 34 "Unable to instantiate application " + appClass 35 + ": " + e.toString(), e); 36 } 37 } 38 mActivityThread.mAllApplications.add(app); 39 mApplication = app; 40 41 if (instrumentation != null) { 42 try { 43 // 调用Application的onCreate方法 44 instrumentation.callApplicationOnCreate(app); 45 } catch (Exception e) { 46 if (!instrumentation.onException(app, e)) { 47 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 48 throw new RuntimeException( 49 "Unable to create application " + app.getClass().getName() 50 + ": " + e.toString(), e); 51 } 52 } 53 } 54 55 ... 56 57 return app; 58}
- 创建ContextImpl对象,并通过Activity的attach方法来完成一些重要数据的初始化
1Context appContext = createBaseContextForActivity(r, activity); 2CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager()); 3Configuration config = new Configuration(mCompatConfiguration); 4if (r.overrideConfig != null) { 5 config.updateFrom(r.overrideConfig); 6} 7if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity " 8 + r.activityInfo.name + " with config " + config); 9Window window = null; 10if (r.mPendingRemoveWindow != null && r.mPreserveWindow) { 11 window = r.mPendingRemoveWindow; 12 r.mPendingRemoveWindow = null; 13 r.mPendingRemoveWindowManager = null; 14} 15activity.attach(appContext, this, getInstrumentation(), r.token, 16 r.ident, app, r.intent, r.activityInfo, title, r.parent, 17 r.embeddedID, r.lastNonConfigurationInstances, config, 18 r.referrer, r.voiceInteractor, window);
ContextImpl是一个很重要的数据结构,很明显是Context的具体实现,Context中大部分逻辑都是由ContextImpl实现的。ContextImpl通过Activity的attach方法来和Activity建立关联,同时在attach方法中还会完成Window的创建并建立自己和Window的关联,Window接收到外部事件输入后将事件传递给Activity。
- 调用Activity的onCreate方法
mInstrumentation.callActivityOnCreate(activity, r.state);
上述代码中调用Activity的onCreate方法,意味着Activity已经完成了整个启动过程。此外还调用了Activity的onStart,OnRestoreInstanceState方法:
1activity.performStart(); 2... 3mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
总结
至此,整个Activity的启动流程已经分析完了,其中还有很多细节需要打磨:
- 启动过程中涉及到的类的作用分别是什么,我们并没有深入分析
- 可以看出,Activity启动最后涉及到Handler消息循环机制,可以参考我的上一篇文章:Android消息机制Handler
- Activity启动过程中AMS的地位显著,但是进程间通信的具体本质我也没有分析,下一步可以分析下Android IPC机制
- Android从开机到点击Icon打开APP的过程中涉及到Launcher(它其实也是一个android应用程序)的启动以及APP进程的创建,我们此处没有提及,以后的博客中我也会整理分析
