Android中Activity的工作过程(一)

PS:本文系转载文章,阅读原文可读性会更好,文章末尾有原文链接
【Android中Activity的工作过程(一)】PS:本文是基于 Android Api 26 来分析源码的。Activity 作为四大组件之一,它内部工作过程系统当然也是做了很多的封装,这种封装使得启动一个 Activity 变得异常简单。在显式调用的情形下,假设我用 MainActivity 启动 Main2Activity,那么通过如下代码即可完成;
Android中Activity的工作过程(一)
文章图片

为了更好的了解显示启动 Activity 时两个 Activity 的声明周期方法调用过程,我们先列出 MainActivity 和 Main2Activity 的代码;(1)MainActivity 代码;
Android中Activity的工作过程(一)
文章图片

(2)Main2Activity 代码;
Android中Activity的工作过程(一)
文章图片

运行一下 app,日志打印如下所示;
Android中Activity的工作过程(一)
文章图片

看,跳转的过程中两个 Activity 的声明周期方法调用顺序是这样的:MainActivity.onPause -> Main2Activity.onCreate -> Main2Activity.onStart -> Main2Activity.onResume -> MainActivity.onStop。由于上面提到的5个生命周期的流程涉及到的源码比较多,这里我们先找 MainActivity 的 onPause 方法流程走向。MainActivity 启动 Main2Activity 时,它内部是怎么做到的呢?我们看一下 Activity 的 startActivity(Intent intent) 方法的实现;
Android中Activity的工作过程(一)
文章图片

startActivity(Intent intent) 方法调用了 Activity 的 startActivity(Intent intent, @Nullable Bundle options) 方法;
Android中Activity的工作过程(一)
文章图片

由于 options 这个参数为空,所以执行的是注释2的代码块,我们看一下 Activity 的 startActivityForResult(@RequiresPermission Intent intent, int requestCode) 方法;
Android中Activity的工作过程(一)
文章图片

startActivityForResult(@RequiresPermission Intent intent, int reque-stCode) 方法调用了 Activity 的 startActivityForResult(@RequiresPermi-ssion Intent intent, int requestCode,@Nullable Bundle options) 方法;
Android中Activity的工作过程(一)
文章图片

看,为什么会执行注释3的代码?这里首先要判断 mParent == null 是否为 true,mParent 就是当前 Activity 的父 Activity,而我们的 Activity 是 MainActivity,它没有父类的 Activity,所以这里的 mParent == null 的结果是 true,实际上,mParent 常用在 ActivityGroup 中,而在API 14开始 ActivityGroup 已经废弃。我们看一下注释4的代码,mInstrumentation 是 Instrumentation 类型的对象,我们看一下 Instrumentation 的 execStartActivity(Context who, IBinder contextThread, IBinder token, Activity target,Intent intent, int requestCode, Bundle options) 方法;
Android中Activity的工作过程(一)
文章图片

我们先看注释6的代码,看这个方法名,好像是检查启动 Activity 的结果,好吧,我们先进去看一下 Instrumentation 的 checkStartActivityResult(int res, Object intent) 方法;
Android中Activity的工作过程(一)
文章图片

里面有很多各种检查的结果,我省略了很多;看注释7,如果我们没有在 AndroidManifest.xml 文件里面注册 Activity,那么就会抛出 Unable to find explicit activity classhave you declared this activity in your AndroidManifest.xml? 的异常。好,我们现在回来看注释5的代码这里,ActivityManager.getService() 拿到的其实是 ActivityManagerService,所以我们往下看 ActivityManagerService 的 startActivity(IApplicationThread caller, String callingPackage,Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) 方法;
Android中Activity的工作过程(一)
文章图片

ActivityManagerService 的startActivity(IApplicationThread caller, String callingPackage,Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) 方法又调用了 ActivityManagerService 的 startActivityAsUser 方法;
Android中Activity的工作过程(一)
文章图片

mActivityStarter 是一个ActivityStarter 实例对象,ActivityManagerService 的 startActivityAsUser(IApplicationThread caller, String callingPackage,Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) 方法调用了 ActivityStarter 的 startActivityMayWait(IApplicationThread caller, int callingUid,String callingPackage, Intent intent, String resolvedType,IVoiceInteractionSe-ssion voiceSession, IVoiceInteractor voiceInteractor,IBinder resultTo, String resultWho, int requestCode, int startFlags,ProfilerInfo profilerInfo, WaitResult outResult,Configuration globalConfig, Bundle bOptions, boolean ignoreTargetSecurity, int userId,IActivityContainer iContainer, TaskRecord inTask, String reason) 方法;final int startActivityMayWait(IApplicationThread caller, int callingUid, String callingPackage, Intent intent, String resolvedType, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, WaitResult outResult, Configuration globalConfig, Bundle bOptions, boolean ignoreTargetSecurity, int userId, IActivityContainer iContainer, TaskRecord inTask, String reason) { ...... synchronized (mService) { ...... //9、 int res = startActivityLocked(caller, intent, ephemeralIntent, resolvedType, aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options, ignoreTargetSecurity, componentSpecified, outRecord, container, inTask, reason); ...... return res; }}看注释9的代码,又调用了 ActivityStarter 的 startActivityLocked(IApplicationThread caller, Intent intent, Intent ephemeralIntent,String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,IVoiceInteractionSession voiceSession, IVoi-ceInteractor voiceInteractor,IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,String callingPackage, int realCallingPid, int realCallingUid, int startFlags,ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,Activity-Record[] outActivity, ActivityStackSupervisor.ActivityContainer contain-er,TaskRecord inTask, String reason) 方法;
Android中Activity的工作过程(一)
文章图片

看注释10的代码,又调用了 ActivityStarter 的 startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,IVoiceInteractionSession voiceSession, IVoiceInteractor voiceIn-teractor,IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,String callingPackage, int realCallingPid, int realCallingUid, int startFlags,ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,ActivityRecord[] outActivity, ActivityStackSupervisor.ActivityContainer container,Ta-skRecord inTask) 方法;
Android中Activity的工作过程(一)
文章图片

看注释11,调用了 ActivityStarter 的 startActivity(final ActivityRecord r, ActivityRecord sourceRecord,IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,ActivityRecord[] outActivity) 方法;
Android中Activity的工作过程(一)
文章图片

看注释12,调用到了 ActivityStarter 的 startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,ActivityRec-ord[] outActivity) 方法;// Note: This method should only be called from {@link startActivity}. private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask, ActivityRecord[] outActivity) { ...... if (mDoResume) { final ActivityRecord topTaskActivity = mStartActivity.getTask().topRunningActivityLocked(); if (!mTargetStack.isFocusable() || (topTaskActivity != null && topTaskActivity.mTaskOverlay && mStartActivity != topTaskActivity)) { ...... } else { ...... //13、 mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity, mOptions); } } else { ...... } ...... return START_SUCCESS; }看注释13的代码,因为我的 Main2Activity 的启动模式是 standard,所以会走这里,mSupervisor 是 ActivityStackSupervisor 类型的实例,我们看一下 ActivityStackSupervisor 的 resumeFocusedStackTopActivityLock-ed(ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) 方法;
Android中Activity的工作过程(一)
文章图片

看注释14,调用了 ActivityStack 的 resumeTopActivityUncheckedLo-cked(ActivityRecord prev, ActivityOptions options) 方法;
Android中Activity的工作过程(一)
文章图片

看注释15,调用了 ActivityStack 的 resumeTopActivityInner-Locked(ActivityRecord prev, ActivityOptions options) 方法;
Android中Activity的工作过程(一)
文章图片

看注释16,调用了 ActivityStack 的 startPausingLocked(boolean userLeaving, boolean uiSleeping,ActivityRecord resuming, boolean pauseImmediately) 方法;
Android中Activity的工作过程(一)
文章图片

看注释17,prev.app.thread 是 ActivityThread 的内部类 ApplicatitonThread ,调用了 AppcationThread 的 schedulePauseActivity(IBinder token, boolean finished,boolean userLeaving, int configChanges, boolean dontReport) 方法;
Android中Activity的工作过程(一)
文章图片

看注释18,因为 finished 为 false,所有第一个参数是 H.PAUSE_ACTIVITY,又调用了 ActivityThread 的内部类 H;
Android中Activity的工作过程(一)
文章图片

看注释19,又调用了 ActivityThread 的 handlePauseActivity(IBinder token, boolean finished,boolean userLeaving, int configChanges, boolean dontReport, int seq) 方法;
Android中Activity的工作过程(一)
文章图片

看注释20,又调用了 ActivityThread 的 performPauseActivity(IBinder token, boolean finished,boolean saveState, String reason) 方法;
Android中Activity的工作过程(一)
文章图片

看注释21,又调用了 ActivityThread 的 performPauseActivity(Activit-yClientRecord r, boolean finished,boolean saveState, String reason) 方法;
Android中Activity的工作过程(一)
文章图片

看注释22,又调用了 ActivityThread 的 performPauseActivity-IfNeeded(ActivityClientRecord r, String reason) 方法;
Android中Activity的工作过程(一)
文章图片

看注释23,mInstrumentation 是 Instrumentation 类型的对象,所以调用了 Instrumentation 的 callActivityOnPause(Activity activity) 方法;
Android中Activity的工作过程(一)
文章图片

看注释24,调用了 Activity 的 performPause 方法;
Android中Activity的工作过程(一)
文章图片

看到注释25了没有,Activity 的 onPause 方法已经找到,我们的目标已经完成,所以这篇文章到这里就写完了。

    推荐阅读