Activity启动流程源码分析


一个Activity启动分为两种启动方式,一种是从Launcher界面上的图标点击启动,另一种是从一个Activity中设置按钮点击启动另外一个Activity。这里先学习下第一种。

在开始学习前给大家推荐一个可以浏览和快速查找Android源码的网站,帮助大家快速学习。

http://androidxref.com/

这篇文章以Nougat - 7.1.1_r6(Android 7.1.1)为例,其源码目录结构地址为:

http://androidxref.com/7.1.1_r6/xref/

这里说下为什么选择android N来写启动流程,因为android N 的binder通信并未使用aidl,更容易理解binder。

Launcher本身也是一个应用程序继承的Activity类,我们选择Android 7.1.1的Launcher2开始学习,这里先不讲系统如何启动Launcher的(有兴趣的可以自己百度),只从Launcher启动一个Activity开始分析。

Launcher的源码工程在:***/packages/apps/Launcher2***

负责启动其他应用程序的源码在:***/src/com/android/Launcher2/Launcher.java***

1. onClick方法中调用startActivitySafely()—>Activity的startActivity()

路径:/packages/apps/Launcher2/src/com/android/launcher2/Launcher.java(line_2035)

public void onClick(View v) {// Make sure that rogue clicks don't get through while allapps is launching, or after the// view has detached (it's possible for this to happen if the view is removed mid touch).if (v.getWindowToken() == null) {return;}if (!mWorkspace.isFinishedSwitchingState()) {return;}Object tag = v.getTag();if (tag instanceof ShortcutInfo) {//open shortcut final Intent intent = ((ShortcutInfo) tag).intent;int[] pos = new int[2];v.getLocationOnScreen(pos);intent.setSourceBounds(new Rect(pos[0], pos[1],pos[0] + v.getWidth(), pos[1] + v.getHeight()));boolean success = startActivitySafely(v, intent, tag);...} else if (tag instanceof FolderInfo) {...}else if (v == mAllAppsButton) {...}
}

通过**Intent.getSourceBounds()**可以获取到应用图标在Launcher中的坐标信息。

然后通过startActivitySafely()打开应用程序或者快捷方式。(line_2215)

boolean startActivitySafely(View v, Intent intent, Object tag) {boolean success = false;try {success = startActivity(v, intent, tag);} catch (ActivityNotFoundException e) {Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();Log.e(TAG, "Unable to launch. tag=" + tag + " intent=" + intent, e);}return success;
}

startActivitySafely()中又调用了Launcher的startActivity()。(line_2174)

boolean startActivity(View v, Intent intent, Object tag) {intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);try {...if (useLaunchAnimation) {...if (user == null || user.equals(android.os.Process.myUserHandle())) {// Could be launching some bookkeeping activitystartActivity(intent, opts.toBundle());} else {...}} else {if (user == null || user.equals(android.os.Process.myUserHandle())) {startActivity(intent);} else {...}}return true;} catch (SecurityException e) {...}return false;
}

Launcher中的startActivity()设置Intent以及相关动画最后调用Activity中的startActivity()开始进入真正启动流程。

2. Activity.startActivity()

路径:/frameworks/base/core/java/android/app/Activity.java(line_4516)

public void startActivity(Intent intent) {this.startActivity(intent, null);
}public void startActivity(Intent intent, @Nullable Bundle options) {if (options != null) {startActivityForResult(intent, -1, options);} else {// Note we want to go through this call for compatibility with// applications that may have overridden the method.startActivityForResult(intent, -1);}
}

这两个方法很简单就是最终调用Activity的startActivityForResult(),-1表示当前Activity结束后不用给上一个Activity(Launcher)返回结果;(line_4220)

public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,@Nullable Bundle options) {if (mParent == null) {options = transferSpringboardActivityOptions(options);Instrumentation.ActivityResult ar =mInstrumentation.execStartActivity(this, mMainThread.getApplicationThread(), mToken, this,intent, requestCode, options);if (ar != null) {mMainThread.sendActivityResult(mToken, mEmbeddedID, requestCode, ar.getResultCode(),ar.getResultData());}if (requestCode >= 0) {mStartedActivity = true;}cancelInputsAndStartExitTransition(options);// TODO Consider clearing/flushing other event sources and events for child windows.} else {...}
}

startActivityForResult中调用Instrumentation类中的execStartActivity()。

3. 分析Instrumentation类的execStartActivity方法

这里要特别说明一下Instrumentation这个类,它是负责监控应用程序和系统交互:

Instrumentation类的路径:/frameworks/base/core/java/android/app/Instrumentation.java

上面mInstrumentation它是一个Instrumentation的实例 主要的作用是Instrumentation是执行application instrumentation代码的基类。当应用程序运行的时候instrumentation处于开启,Instrumentation将在任何应用程序运行前初始化,可以通过它监测系统与应用程序之间的交互。一个应用程序中只有一个Instrumentation对象,每个Activity内部都有一个该对象的引用。Instrumentation可以理解为应用进程的管家, ActivityThread要创建或者暂停某 个 Activity时,是通过这个“管家”进行的,设置这个管家的好处是可以统计所有的“ 开销”,开销的信息保存在“ 管家” 那里。其实正如其名称所示,Instrumentation就是为了 “测量”、“统计”,因为管家掌握了所有的“ 开销”,自然也就具有了统计的功能。

这个execStartActivity方法返回结果是ActivityResult对象,因为Launcher启动Activity不需要返回结果,即这里的 ar==null,所以不会调用sendActivityResult()。

execStartActivity方法有很多参数,分别是:

  • this:Context上下文对象,或者当前Activity对象;
  • mMainThread.getApplicationThread():获取当前应用程序的ApplicationThread(即Launcher),是一个Binder,ActivityManagerService使用这个Binder与ActivityThread交互;
  • mToken:一个Binder对象,暂时还不知道这个binder对象是做什么的,后面解释;
  • this:Activity的target;
  • intent:Intent对象,可以附带一些数据;
  • requestCode:这里是-1;
  • options:Bundle分装的数据,这里为null。

下面继续看Instrumentation的execStartActivity():

路径:/frameworks/base/core/java/android/app/Instrumentation.java(line_1492)

public ActivityResult execStartActivity(Context who, IBinder contextThread, IBinder token, Activity target,Intent intent, int requestCode, Bundle options) {IApplicationThread whoThread = (IApplicationThread) contextThread;......try {intent.migrateExtraStreamToClipData();intent.prepareToLeaveProcess(who);int result = ActivityManagerNative.getDefault().startActivity(whoThread, who.getBasePackageName(), intent,intent.resolveTypeIfNeeded(who.getContentResolver()),token, target != null ? target.mEmbeddedID : null,requestCode, 0, null, options);checkStartActivityResult(result, intent);} catch (RemoteException e) {throw new RuntimeException("Failure from system", e);}return null;
}

4. ActivityManagerNative.getDefault().startActivity()

这个方法是ActivityManagerProxy的,通过binder通信调用ActivityManagerService的startActivity()方法,可以说ActivityManagerProxy是一个远程的ActivityManagerService对象。如果这块难理解的话可以自行查阅IPC通信机制,这里调用binder的transact()通信。

ActivityManagerProxy是ActivityManagerNative的内部类,路径:frameworks/base/core/java/android/app/ActivityManagerNative.java(line_3062)

class ActivityManagerProxy implements IActivityManager{public ActivityManagerProxy(IBinder remote){mRemote = remote;}public IBinder asBinder(){return mRemote;}public int startActivity(IApplicationThread caller, String callingPackage, Intent intent,String resolvedType, IBinder resultTo, String resultWho, int requestCode,int startFlags, ProfilerInfo profilerInfo, Bundle options) throws RemoteException {Parcel data = Parcel.obtain();Parcel reply = Parcel.obtain();data.writeInterfaceToken(IActivityManager.descriptor);data.writeStrongBinder(caller != null ? caller.asBinder() : null);data.writeString(callingPackage);intent.writeToParcel(data, 0);data.writeString(resolvedType);data.writeStrongBinder(resultTo);data.writeString(resultWho);data.writeInt(requestCode);data.writeInt(startFlags);if (profilerInfo != null) {data.writeInt(1);profilerInfo.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);} else {data.writeInt(0);}if (options != null) {data.writeInt(1);options.writeToParcel(data, 0);} else {data.writeInt(0);}mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);reply.readException();int result = reply.readInt();reply.recycle();data.recycle();return result;}......
}

这个方法有好多参数,分别列举:

  • IApplicationThread caller:传递过来的contextThread;
  • String callingPackage:获取的一些application的package信息;//获取Launcher的还是要打开的Activity的
  • Intent intent:intent对象;
  • String resolvedType:这里传递的是intent.resolveTypeIfNeeded(who.getContentResolver())返回这个intent的MIME类型,根据AndroidManifest.xml设置MainActivity的MIME类型来取值,没有设置即为null;
  • IBinder resultTo:mToken,binder对象;
  • String resultWho:target.mEmbeddedID,虽然target不为空,但是mEmbeddedID是null;
  • int requestCode:-1不需要Activity结束返回值;
  • int startFlags:0;
  • ProfilerInfo profilerInfo:分析工具,这里也是null;
  • Bundle options:bundle中存储的数据,这里是null。

通过mRemote.transact()调用ActivityManagerService的startActivity()。

5. ActivityManagerService.startActivity()

路径:/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java(line_4328)

public final int startActivity(IApplicationThread caller, String callingPackage,Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,resultWho, requestCode, startFlags, profilerInfo, bOptions,UserHandle.getCallingUserId());
}

startActivity方法中直接调用startActivityAsUser()(都是AMS里的方法:line_4356)唯一的区别就是多了一个userId参数,这个UserId可以通过Binder机制的getCallingUid()获取到。有了这个UserId,ActivityManagerService就可以检查调用者的权限。

public final int startActivityAsUser(IApplicationThread caller, String callingPackage,Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {enforceNotIsolatedCaller("startActivity");userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),userId, false, ALLOW_FULL_ONLY, "startActivity", null);// TODO: Switch to user app stacks here.return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,profilerInfo, null, null, bOptions, false, userId, null, null);
}

enforceNotIsolatedCaller(“startActivity”)检查调用者是否被隔离,如果被隔离会抛出SecurityException。

void enforceNotIsolatedCaller(String caller) {if (UserHandle.isIsolated(Binder.getCallingUid())) {throw new SecurityException("Isolated process not allowed to call " + caller);}
}

handleIncomingUser()检查调用者是否有权限执行call操作。

最后调用ActivityStarter的startActivityMayWait()。

6. ActivityStarter.startActivityMayWait()

路径:/frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java(line_715)

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, IActivityManager.WaitResult outResult, Configuration config,Bundle bOptions, boolean ignoreTargetSecurity, int userId,IActivityContainer iContainer, TaskRecord inTask) {....//匹配隐式IntentResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId);if (rInfo == null) {....}// Collect information about the target of the Intent.//获取ActivityManifest.xml中MainActivity信息ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);......synchronized (mService) {......final int realCallingPid = Binder.getCallingPid();final int realCallingUid = Binder.getCallingUid();int callingPid;if (callingUid >= 0) {callingPid = -1;} else if (caller == null) {callingPid = realCallingPid;callingUid = realCallingUid;} else {callingPid = callingUid = -1;}final ActivityStack stack;if (container == null || container.mStack.isOnHomeDisplay()) {stack = mSupervisor.mFocusedStack;} else {stack = container.mStack;}......if (aInfo != null &&(aInfo.applicationInfo.privateFlags& ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0) {//判断是不是一个重量级进程if (aInfo.processName.equals(aInfo.applicationInfo.packageName)) {final ProcessRecord heavy = mService.mHeavyWeightProcess;if (heavy != null && (heavy.info.uid != aInfo.applicationInfo.uid|| !heavy.processName.equals(aInfo.processName))) {......}}}final ActivityRecord[] outRecord = new ActivityRecord[1];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);Binder.restoreCallingIdentity(origId);......if (outResult != null) {......}final ActivityRecord launchedActivity = mReusedActivity != null? mReusedActivity : outRecord[0];mSupervisor.mActivityMetricsLogger.notifyActivityLaunched(res, launchedActivity);return res;}
}

先看方法参数:

  • IApplicationThread caller:前面方法传过来的ApplicationThread;
  • int callingUid:-1
  • String callingPackage:上面方法传过来的callingPackage;
  • Intent intent:上面方法传递过来intent对象;
  • String resolvedType:之前方法传过来,为null;
  • IVoiceInteractionSession voiceSession:null;
  • IVoiceInteractor voiceInteractor:null;
  • IBinder resultTo:Launcher传过来的binder对象;
  • String resultWho:前面方法传过来resultWho;
  • int requestCode:-1;
  • int startFlags:上个方法传递过来值;
  • ProfilerInfo profilerInfo:传递过来的值;
  • IActivityManager.WaitResult outResult:null;
  • Configuration config:null;
  • Bundle bOptions:intent附带的值,这里为null;
  • boolean ignoreTargetSecurity:false;
  • int userId:上一个方法获取到的userId;
  • IActivityContainer iContainer:null;
  • TaskRecord inTask:null。

代码很长,可以分为以下几个部分:

(1)判断是显式Intent还是隐式Intent来通过PMS获取Activity的package信息:

ResolveInfo resolveIntent(Intent intent, String resolvedType, int userId, int flags) {try {return AppGlobals.getPackageManager().resolveIntent(intent, resolvedType,PackageManager.MATCH_DEFAULT_ONLY | flags| ActivityManagerService.STOCK_PM_FLAGS, userId);} catch (RemoteException e) {}return null;
}

(2)通过resolveActivity获取上面得到package信息中的Activity信息:

ActivityInfo resolveActivity(Intent intent, ResolveInfo rInfo, int startFlags,ProfilerInfo profilerInfo) {final ActivityInfo aInfo = rInfo != null ? rInfo.activityInfo : null;if (aInfo != null) {intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));// Don't debug things in the system processif (!aInfo.processName.equals("system")) {......}}return aInfo;
}

aInfo.applicationInfo.packageName获取要启动MainActivity的包名,rInfo.activityInfo获取的是MainActivity的包名.类名(MainActivity),传给intent设置Component。

(3)接着会判断目标进程是不是重量级进程(heavy-weight),判断是否已经存在不同于目标进程的重量级进程,如果存在则会重新赋值intent。之后会继续执行startActivityLocked()。

(4)最后会根据传入的outResult是否为空来等待是否将执行的结果写入到outResult中,在源码中是一个while循环来达到等待的目的,我们在startActivity时传入的outResult为null,所在在这个过程中不会执行while循序。不过这或许是startActivityMayWait名字中有一个mayWait的原因。

7. ActivityStarter.startActivityLocked()

带Locked的方法一般都是要求同步的,因为方法中会操作临界资源。

路径:/frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java(line_230)

final int startActivityLocked(IApplicationThread caller, Intent intent, Intent ephemeralIntent,String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,IVoiceInteractionSession voiceSession, IVoiceInteractor 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,ActivityRecord[] outActivity, ActivityStackSupervisor.ActivityContainer container,TaskRecord inTask) {int err = ActivityManager.START_SUCCESS;ProcessRecord callerApp = null;//判断applicationThread有没有被系统kill掉if (caller != null) {callerApp = mService.getRecordForAppLocked(caller);if (callerApp != null) {callingPid = callerApp.pid;callingUid = callerApp.info.uid;} else {......}}final int userId = aInfo != null ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;ActivityRecord sourceRecord = null;ActivityRecord resultRecord = null;if (resultTo != null) {sourceRecord = mSupervisor.isInAnyStackLocked(resultTo);//resultTo是Launcher传过来的binder对象,这里通过这个binder对象获取Launcher这个Activity的信息存在sourceRecord里......}final int launchFlags = intent.getFlags();if ((launchFlags & Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 && sourceRecord != null) {//Intent.FLAG_ACTIVITY_FORWARD_RESULT:用于完成跨越式传递//例如ActivityA启动ActivityB最后启动ActivityC,ActivityC结束后希望直接返回ActivityA而不是ActivityB,}if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {......}if (err == ActivityManager.START_SUCCESS && aInfo == null) {......}if (err == ActivityManager.START_SUCCESS && sourceRecord != null&& sourceRecord.task.voiceSession != null) {......}if (err == ActivityManager.START_SUCCESS && voiceSession != null) {......}final ActivityStack resultStack = resultRecord == null ? null : resultRecord.task.stack;......//检测启动Activity权限,做一些启动准备工作 boolean abort = !mSupervisor.checkStartAnyActivityPermission(intent, aInfo, resultWho,requestCode, callingPid, callingUid, callingPackage, ignoreTargetSecurity, callerApp,resultRecord, resultStack, options);//检测启动Activity权限abort |= !mService.mIntentFirewall.checkStartActivity(intent, callingUid,callingPid, resolvedType, aInfo.applicationInfo);......//将即将要启动的Activity信息存入r中ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho,requestCode, componentSpecified, voiceSession != null, mSupervisor, container,options, sourceRecord);......final ActivityStack stack = mSupervisor.mFocusedStack;if (voiceSession == null && (stack.mResumedActivity == null|| stack.mResumedActivity.info.applicationInfo.uid != callingUid)) {if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid,realCallingPid, realCallingUid, "Activity start")) {PendingActivityLaunch pal =  new PendingActivityLaunch(r,sourceRecord, startFlags, stack, callerApp);mPendingActivityLaunches.add(pal);ActivityOptions.abort(options);return ActivityManager.START_SWITCHES_CANCELED;}}if (mService.mDidAppSwitch) {mService.mAppSwitchesAllowedTime = 0;} else {mService.mDidAppSwitch = true;}doPendingActivityLaunchesLocked(false);try {//使用WMS进行Activity的绘制mService.mWindowManager.deferSurfaceLayout();//根据不同启动模式来启动Activityerr = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor, startFlags,true, options, inTask);} finally {mService.mWindowManager.continueSurfaceLayout();}postStartActivityUncheckedProcessing(r, err, stack.mStackId, mSourceRecord, mTargetStack);return err;
}

(1)startActivityLocked()方法做的第一件事就是判断caller进程是否还存在,因为caller进程在发出启动请求后,被系统kill掉了,所以这里还是要判断一下,如果已经kill掉了,直接返回。如果还存活着就从caller得到调用者的进程信息,并保存在callerApp变量中,这里就是Launcher应用程序的进程信息了;

(2)接着处理launchFlags,这个见代码注释;

(3)接着会判断是否匹配到Intent的目标,如果没有匹配到,那么将不会再处理该Intent,程序直接返回。如果匹配到,那么接着校验caller是否有权限启动目标Activity。权限必须全部校验通过,否则将报SecurityException;

(4)再接下来,创建即将要启动的Activity的相关信息以及上面的判断结果保存在ActivityRecord的r实例中;

(5)在接下来调用WMS来进行Activity UI的初始绘制(这里主要讲Activity启动过程,绘制后面分析);

(6)最后调用startActivityUnchecked()进行下一步操作。

8. ActivityStarter.startActivityUnchecked()

路径:/frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java(line_1024)

private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask) {//校验intent的flag是否是特定的flagsetInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,voiceInteractor);//判断是否需要启动新的taskcomputeLaunchingTaskFlags();//保存和清除sourceRecord和sourceTaskcomputeSourceStack();//给intent设置flagmIntent.setFlags(mLaunchFlags);mReusedActivity = getReusableIntentActivity();final int preferredLaunchStackId =(mOptions != null) ? mOptions.getLaunchStackId() : INVALID_STACK_ID;if (mReusedActivity != null) {.......if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0|| mLaunchSingleInstance || mLaunchSingleTask) {final ActivityRecord top = mReusedActivity.task.performClearTaskForReuseLocked(mStartActivity, mLaunchFlags);if (top != null) {if (top.frontOfTask) {top.task.setIntent(mStartActivity);}ActivityStack.logStartActivity(AM_NEW_INTENT, mStartActivity, top.task);top.deliverNewIntentLocked(mCallingUid, mStartActivity.intent,mStartActivity.launchedFromPackage);}}......}......final ActivityStack topStack = mSupervisor.mFocusedStack;final ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(mNotTop);final boolean dontStart = top != null && mStartActivity.resultTo == null&& top.realActivity.equals(mStartActivity.realActivity)&& top.userId == mStartActivity.userId&& top.app != null && top.app.thread != null&& ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0|| mLaunchSingleTop || mLaunchSingleTask);if (dontStart) {......return START_DELIVERED_TO_TOP;}boolean newTask = false;final TaskRecord taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null)? mSourceRecord.task : null;// Should this be considered a new task?if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask&& (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {newTask = true;setTaskFromReuseOrCreateNewTask(taskToAffiliate);......} else if (mSourceRecord != null) {......} else if (mInTask != null) {......} else {setTaskToCurrentTopOrCreateNewTask();}mService.grantUriPermissionFromIntentLocked(mCallingUid, mStartActivity.packageName,mIntent, mStartActivity.getUriPermissionsLocked(), mStartActivity.userId);if (mSourceRecord != null && mSourceRecord.isRecentsActivity()) {mStartActivity.task.setTaskToReturnTo(RECENTS_ACTIVITY_TYPE);}......mTargetStack.startActivityLocked(mStartActivity, newTask, mKeepCurTransition, mOptions);//判断当前Activity是否可以onResumeif (mDoResume) {if (!mLaunchTaskBehind) {// TODO(b/26381750): Remove this code after verification that all the decision// points above moved targetStack to the front which will also set the focus// activity.mService.setFocusedActivityLocked(mStartActivity, "startedActivity");}final ActivityRecord topTaskActivity = mStartActivity.task.topRunningActivityLocked();if (!mTargetStack.isFocusable()|| (topTaskActivity != null && topTaskActivity.mTaskOverlay&& mStartActivity != topTaskActivity)) {mTargetStack.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);mWindowManager.executeAppTransition();} else {mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,mOptions);}} else {mTargetStack.addRecentActivityLocked(mStartActivity);}mSupervisor.updateUserStackLocked(mStartActivity.userId, mTargetStack);mSupervisor.handleNonResizableTaskIfNeeded(mStartActivity.task, preferredLaunchStackId, mTargetStack.mStackId);return START_SUCCESS;
}

代码比较长,一点一点来看:

(1)使用setInitialState()方法校验Intent特定的flag和是否可以resume判断,部分代码如下:

private void setInitialState(ActivityRecord r, ActivityOptions options, TaskRecord inTask,boolean doResume, int startFlags, ActivityRecord sourceRecord,IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {mLaunchSingleTop = r.launchMode == LAUNCH_SINGLE_TOP;mLaunchSingleInstance = r.launchMode == LAUNCH_SINGLE_INSTANCE;mLaunchSingleTask = r.launchMode == LAUNCH_SINGLE_TASK;mLaunchFlags = adjustLaunchFlagsToDocumentMode(r, mLaunchSingleInstance, mLaunchSingleTask, mIntent.getFlags());......mDoResume = doResume;......mSupervisor.mUserLeaving = (mLaunchFlags & FLAG_ACTIVITY_NO_USER_ACTION) == 0;......mNotTop = (mLaunchFlags & FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? r : null;......if ((startFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {......if (!checkedCaller.realActivity.equals(r.realActivity)) {// Caller is not the same as launcher, so always needed.mStartFlags &= ~START_FLAG_ONLY_IF_NEEDED;}}mNoAnimation = (mLaunchFlags & FLAG_ACTIVITY_NO_ANIMATION) != 0;
}

根据根据AndroidManifest.xml文件中配置的launchMode属值来判断Activity启动方式(standard、singleTop、singleTask、singleInstance),同时还有几种flag,解释一下:

  • FLAG_ACTIVITY_NO_USER_ACTION:这个flag表示不是用户触发的启动Activity,而是由于像来电,闹铃等触发的Activity启动,它会阻止普通的onUserLeaveHint()方法的回调;
  • FLAG_ACTIVITY_PREVIOUS_IS_TOP:如果给Intent对象设置了这个标记,并且这个Intent对象被用于从一个既存的Activity中启动一个新的Activity,这个Activity不能用于接受发送给顶层Activity的新的Intent对象,通常认为使用这个标记启动的Activity会被自己立即终止;
  • FLAG_ACTIVITY_RESET_TASK_IF_NEEDED:如果给Intent对象设置了这个标记,并且这个Activity在一个新任务中被启动,也可以在既存的任务堆栈中被带到顶层,那么它就会被作为任务的前门来启动,有时候也可以避免自己启动自己;
  • FLAG_ACTIVITY_NO_ANIMATION:如果给Intent对象设置了这个标记,那么将会阻止系统在Activity间切换的动画变换。

(2)computeLaunchingTaskFlags()判断是否需要启动新的task,其核心代码如下:

private void computeLaunchingTaskFlags() {......if (mInTask == null) {if (mSourceRecord == null) {// This activity is not being started from another...  in this// case we -always- start a new task.if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) == 0 && mInTask == null) {Slog.w(TAG, "startActivity called from non-Activity context; forcing " +"Intent.FLAG_ACTIVITY_NEW_TASK for: " + mIntent);mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;}} else if (mSourceRecord.launchMode == LAUNCH_SINGLE_INSTANCE) {// The original activity who is starting us is running as a single// instance...  this new activity it is starting must go on its// own task.mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;} else if (mLaunchSingleInstance || mLaunchSingleTask) {// The activity being started is a single instance...  it always// gets launched into its own task.mLaunchFlags |= FLAG_ACTIVITY_NEW_TASK;}}
}

如果mSourceRecord为null,表明我们应该新开一个task,也就是会设置mLaunchFlags 为FLAG_ACTIVITY_NEW_TASK。如果mSourceRecord的launchMode为LAUNCH_SINGLE_INSTANCE或者目标Activity的启动模式为singleTask或者singleInstance都需要重新创建一个task。

(3)computeSourceStack()方法判断如果是NEW_TASK,保存sourceRecord和task的intent信息,最后将sourceRecord和sourceTask设置为null;

(4)为intent设置flag;

(5)后面判断当前在堆栈顶端的Activity是否就是即将要启动的Activity,有些情况下,如果即将要启动的Activity就在堆栈的顶端,那么,就不会重新启动这个Activity的别一个实例了。现在处理堆栈顶端的Activity是Launcher,与我们即将要启动的MainActivity不是同一个Activity,因此要在一个新的Task里面来启动这个Activity了,于是新创建一个Task:setTaskToCurrentTopOrCreateNewTask();

(6)在后面调用ActivityStack的startActivityLocked()方法与WMS交互。

ActivityStack这个类的路径:/frameworks/base/services/core/java/com/android/server/am/ActivityStack.java

这个方法处理和WindowManagerService之间的交互,保证Activity对应的UI能在屏幕上显示出来。

final void startActivityLocked(ActivityRecord r, boolean newTask, boolean keepCurTransition,ActivityOptions options) {TaskRecord rTask = r.task;final int taskId = rTask.taskId;// mLaunchTaskBehind tasks get placed at the back of the task stack.if (!r.mLaunchTaskBehind && (taskForIdLocked(taskId) == null || newTask)) {insertTaskAtTop(rTask, r);mWindowManager.moveTaskToTop(taskId);}TaskRecord task = null;......task = r.task;task.addActivityToTop(r);task.setFrontOfTask();r.putInHistory();if (!isHomeStack() || numActivities() > 0) {boolean showStartingIcon = newTask;ProcessRecord proc = r.app;if (proc == null) {proc = mService.mProcessNames.get(r.processName, r.info.applicationInfo.uid);}if (proc == null || proc.thread == null) {showStartingIcon = true;}if ((r.intent.getFlags() & Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) {mWindowManager.prepareAppTransition(TRANSIT_NONE, keepCurTransition);mNoAnimActivities.add(r);} else {mWindowManager.prepareAppTransition(newTask? r.mLaunchTaskBehind? TRANSIT_TASK_OPEN_BEHIND: TRANSIT_TASK_OPEN: TRANSIT_ACTIVITY_OPEN, keepCurTransition);mNoAnimActivities.remove(r);}//在WindowManagerService中注册appToken,只有注册了才能显示出来addConfigOverride(r, task);boolean doShow = true;......} else {......}if (VALIDATE_TOKENS) {//调用WindowManagerService的validateAppTokens()validateAppTokensLocked();}
}

首先判断目标Activity所在的task是不是新建的task,如果不是在新task,那么还得查询是哪一个task;

接着将目标Activity放到整个stack的最顶层,这样才能和用户产生交互;

之后还会根据之前是否有FLAG_ACTIVITY_NO_ANIMATION标记来决定是否需要执行切换动画;

一个Activity的UI能在屏幕上显示出来,必须通过appToken在WindowManagerService中已经注册;

最后调用WMS的validateAppTokensLocked()验证是否注册成功。

(7)ActivityStack中的startActivityLocked()执行完后会执行下面代码:

if (mDoResume) {if (!mLaunchTaskBehind) {// TODO(b/26381750): Remove this code after verification that all the decision// points above moved targetStack to the front which will also set the focus// activity.mService.setFocusedActivityLocked(mStartActivity, "startedActivity");}final ActivityRecord topTaskActivity = mStartActivity.task.topRunningActivityLocked();if (!mTargetStack.isFocusable()|| (topTaskActivity != null && topTaskActivity.mTaskOverlay&& mStartActivity != topTaskActivity)) {mTargetStack.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);mWindowManager.executeAppTransition();} else {mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,mOptions);}} else {mTargetStack.addRecentActivityLocked(mStartActivity);}

这里的mDoResume = doResume = true,doResume是之前传过来的参数直接为true,所以会执行上面的代码就会调用ActivityStackSupervisor类中的resumeFocusedStackTopActivityLocked()。

9. ActivityStackSupervisor.resumeFocusedStackTopActivityLocked()

路径:/frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java(line_1826)

boolean resumeFocusedStackTopActivityLocked(ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {if (targetStack != null && isFocusedStack(targetStack)) {return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);}final ActivityRecord r = mFocusedStack.topRunningActivityLocked();if (r == null || r.state != RESUMED) {mFocusedStack.resumeTopActivityUncheckedLocked(null, null);}return false;
}

这个方法中又调用ActivityStack的resumeTopActivityUncheckedLocked()。

路径:/frameworks/base/services/core/java/com/android/server/am/ActivityStack.java(line_2113)

boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {if (mStackSupervisor.inResumeTopActivity) {return false;}boolean result = false;try {......result = resumeTopActivityInnerLocked(prev, options);} finally {mStackSupervisor.inResumeTopActivity = false;}return result;
}

继续调用ActivityStack的resumeTopActivityInnerLocked()方法。

10. ActivityStack.resumeTopActivityInnerLocked()

路径:/frameworks/base/services/core/java/com/android/server/am/ActivityStack.java(line_2134)

private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {//AMS是否启动,没有启动或者没有正在启动直接返回falseif (!mService.mBooting && !mService.mBooted) {return false;}//判断要启动的Activity的上级Activity是否是Resume状态,不是直接返回falseActivityRecord parent = mActivityContainer.mParentActivity;if ((parent != null && parent.state != ActivityState.RESUMED) ||!mActivityContainer.isAttachedLocked()) {return false;}......//这里的next是Launcherfinal ActivityRecord next = topRunningActivityLocked();final TaskRecord prevTask = prev != null ? prev.task : null;......next.delayedResume = false;// 判断要resume的Activity是否是resume状态if (mResumedActivity == next && next.state == ActivityState.RESUMED &&mStackSupervisor.allResumedActivitiesComplete()) {......return false;}// 判断要resume的Activity所在Task,这里是new Task,故不执行此iffinal TaskRecord nextTask = next.task;if (prevTask != null && prevTask.stack == this &&prevTask.isOverHomeStack() && prev.finishing && prev.frontOfTask) {......}/*1.判断系统是否休眠;2.把当处于Resumed状态的Activity推入Paused状态,然后才可以启动新的Activity。*/if (mService.isSleepingOrShuttingDownLocked()&& mLastPausedActivity == next&& mStackSupervisor.allPausedActivitiesComplete()) {.......return false;}......// 把当前resume的Activity(Launcher)推入pause状态final boolean dontWaitForPause = (next.info.flags & FLAG_RESUME_WHILE_PAUSING) != 0;boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, next, dontWaitForPause);if (mResumedActivity != null) {pausing |= startPausingLocked(userLeaving, false, next, dontWaitForPause);}......//WMS显示UIif (prev != null && prev != next) {if (!mStackSupervisor.mWaitingVisibleActivities.contains(prev)&& next != null && !next.nowVisible) {mStackSupervisor.mWaitingVisibleActivities.add(prev);} else {if (prev.finishing) {mWindowManager.setAppVisibility(prev.appToken, false);} else {//log}}}......}return true;
}

(1)首先判断AMS的状态以及要启动Activity的上级Activity是否是resume状态;

(2)调用 topRunningActivityLocked()方法获取当前栈顶的Activity(Launcher)信息存入next中;

(3)确定当前Activity可以执行resume操作;

(4)把当前resume状态的Activity推入Pause状态,但是在将当前这个Resumed状态的Activity推入Paused状态之前,首先要看一下当前是否有Activity正在进入Pausing状态,如果有的话,当前这个Resumed状态的Activity就要稍后才能进入Paused状态了,这样就保证了所有需要进入Paused状态的Activity串行处理;

(5)调用startPausingLocked方法将当前resume状态的Activity推入pause状态;

(6)之后进行WMS界面显示操作。

11. ActivityStack.startPausingLocked()

路径:/frameworks/base/services/core/java/com/android/server/am/ActivityStack.java(line_1089)

final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping,ActivityRecord resuming, boolean dontWait) {if (mPausingActivity != null) {.......}ActivityRecord prev = mResumedActivity;......mResumedActivity = null;mPausingActivity = prev;mLastPausedActivity = prev;......if (prev.app != null && prev.app.thread != null) {try {mService.updateUsageStats(prev, false);prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,userLeaving, prev.configChangeFlags, dontWait);} catch (Exception e) {......}} else {......}......
}

函数首先把mResumedActivity保存在本地变量prev中。在上一步中,说到mResumedActivity就是Launcher,因此,这里通过prev.app.thread把Launcher进程中的ApplicationThread对象取出来,通过它来通知Launcher这个Activity它要进入Paused状态了。这里的prev.app.thread是一个ApplicationThread对象的远程接口,通过调用这个远程接口ApplicationThreadProxy的schedulePauseActivity()来通知Launcher进入Paused状态。

12. ApplicationThreadNative.ApplicationThreadProxy.schedulePauseActivity()

路径:/frameworks/base/core/java/android/app/ApplicationThreadNative.java(line_776)

class ApplicationThreadProxy implements IApplicationThread {......public final void schedulePauseActivity(IBinder token, boolean finished,boolean userLeaving, int configChanges, boolean dontReport) throws RemoteException {Parcel data = Parcel.obtain();data.writeInterfaceToken(IApplicationThread.descriptor);data.writeStrongBinder(token);data.writeInt(finished ? 1 : 0);data.writeInt(userLeaving ? 1 :0);data.writeInt(configChanges);data.writeInt(dontReport ? 1 : 0);mRemote.transact(SCHEDULE_PAUSE_ACTIVITY_TRANSACTION, data, null,IBinder.FLAG_ONEWAY);data.recycle();}
}

这块代码是不是很熟悉呢,前面在binder通信调用AMS的startActivity方法就见过,这里同样是binder通信,不过这次通过通信机制进入的是ActivityThread的schedulePauseActivity方法。

13. ActivityThread.schedulePauseActivity()

路径:/frameworks/base/core/java/android/app/ActivityThread.java(line_661)

public final void schedulePauseActivity(IBinder token, boolean finished,boolean userLeaving, int configChanges, boolean dontReport) {int seq = getLifecycleSeq();sendMessage(finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY,token,(userLeaving ? USER_LEAVING : 0) | (dontReport ? DONT_REPORT : 0),configChanges,seq);
}

调用自身的sendMessage方法(line_2509):

private void sendMessage(int what, Object obj, int arg1, int arg2, int seq) {Message msg = Message.obtain();msg.what = what;SomeArgs args = SomeArgs.obtain();args.arg1 = obj;args.argi1 = arg1;args.argi2 = arg2;args.argi3 = seq;msg.obj = args;mH.sendMessage(msg);
}

这里首先将相关信息封装成一个msg,然后通过mH成员变量发送出去,mH的类型是H,继承于Handler类,是ActivityThread的内部类,因此,这个消息最后由H.handleMessage(line_1468)来处理。

private class H extends Handler {......public void handleMessage(Message msg) {if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));switch (msg.what) {case PAUSE_ACTIVITY: {Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");SomeArgs args = (SomeArgs) msg.obj;handlePauseActivity((IBinder) args.arg1, false,(args.argi1 & USER_LEAVING) != 0, args.argi2,(args.argi1 & DONT_REPORT) != 0, args.argi3);maybeSnapshot();Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);} break;case PAUSE_ACTIVITY_FINISHING: {Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");SomeArgs args = (SomeArgs) msg.obj;handlePauseActivity((IBinder) args.arg1, true, (args.argi1 & USER_LEAVING) != 0,args.argi2, (args.argi1 & DONT_REPORT) != 0, args.argi3);Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);} break;......}......
}

从schedulePauseActivity方法里传过来的参数可以看到msg.what = PAUSE_ACTIVITY|PAUSE_ACTIVITY_FINISHING,而这里并没有finish故为 PAUSE_ACTIVITY,最后调用ActivityThread类的handlePauseActivity函数进一步处理。传递的参数args.arg1是上面传来的token,Launcher的远程Binder引用。

继续看handlePauseActivity()(line_3651):

private void handlePauseActivity(IBinder token, boolean finished,boolean userLeaving, int configChanges, boolean dontReport, int seq) {ActivityClientRecord r = mActivities.get(token);......if (r != null) {//Slog.v(TAG, "userLeaving=" + userLeaving + " handling pause of " + r);if (userLeaving) {performUserLeavingActivity(r);}r.activity.mConfigChangeFlags |= configChanges;performPauseActivity(token, finished, r.isPreHoneycomb(), "handlePauseActivity");// Make sure any pending writes are now committed.if (r.isPreHoneycomb()) {QueuedWork.waitToFinish();}// Tell the activity manager we have paused.if (!dontReport) {try {ActivityManagerNative.getDefault().activityPaused(token);} catch (RemoteException ex) {throw ex.rethrowFromSystemServer();}}mSomeActivitiesChanged = true;}
}

函数首先将Binder引用token转换成ActivityRecord的远程接口ActivityClientRecord,然后做了三个事情:

(1)如果userLeaving为true,则通过调用performUserLeavingActivity函数来调用Activity.onUserLeaveHint通知Activity,用户要离开它了;

(2)调用performPauseActivity函数来调用Activity.onPause函数,我们知道,在Activity的生命周期中,当它要让位于其它的Activity时,系统就会调用它的onPause函数,如下代码所示;

final Bundle performPauseActivity(ActivityClientRecord r, boolean finished,boolean saveState, String reason) {......ArrayList<OnActivityPausedListener> listeners;synchronized (mOnPauseListeners) {listeners = mOnPauseListeners.remove(r.activity);}int size = (listeners != null ? listeners.size() : 0);for (int i = 0; i < size; i++) {listeners.get(i).onPaused(r.activity);}return !r.activity.mFinished && saveState ? r.state : null;
}

(3)它通知ActivityManagerService,这个Activity已经进入Paused状态了,ActivityManagerService现在可以启动MainActivity了,ActivityThread通知AMS肯定得用到Binder通信,这里调用ActivityManagerProxy的activityPaused()。

14. ActivityManagerNative.ActivityManagerProxy.activityPaused()

路径: /frameworks/base/core/java/android/app/ActivityManagerNative.java (line_3615)

public void activityPaused(IBinder token) throws RemoteException{Parcel data = Parcel.obtain();Parcel reply = Parcel.obtain();data.writeInterfaceToken(IActivityManager.descriptor);data.writeStrongBinder(token);mRemote.transact(ACTIVITY_PAUSED_TRANSACTION, data, reply, 0);reply.readException();data.recycle();reply.recycle();
}

果不其然,使用Binder通信调用AMS的activityPaused()。

15. ActivityManagerService.activityPaused()

路径:/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java(line_6913)

public final void activityPaused(IBinder token) {final long origId = Binder.clearCallingIdentity();synchronized(this) {ActivityStack stack = ActivityRecord.getStackLocked(token);if (stack != null) {stack.activityPausedLocked(token, false);}}Binder.restoreCallingIdentity(origId);
}

可以看到这里调用ActivityStack的activityPausedLocked()方法。

16. ActivityStack.activityPausedLocked()

路径:/frameworks/base/services/core/java/com/android/server/am/ActivityStack.java(line_1202)

final void activityPausedLocked(IBinder token, boolean timeout) {final ActivityRecord r = isInStackLocked(token);if (r != null) {mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);if (mPausingActivity == r) {completePauseLocked(true, null);return;} else {......}}......
}

首先调用isInstackLocked(token)通过token这个Launcher的远程binder获取Launcher信息存入变量r中,而这里的mPausingActivity正好是Launcher,所以执行completePauseLocked()。

17. ActivityStack.completePauseLocked()

路径:/frameworks/base/services/core/java/com/android/server/am/ActivityStack.java(line_1283)

private void completePauseLocked(boolean resumeNext, ActivityRecord resuming) {//LauncherActivityRecord prev = mPausingActivity;if (prev != null) {final boolean wasStopping = prev.state == ActivityState.STOPPING;prev.state = ActivityState.PAUSED;if (prev.finishing) {prev = finishCurrentActivityLocked(prev, FINISH_AFTER_VISIBLE, false);} else if (prev.app != null) {......} else {prev = null;}......mPausingActivity = null;}if (resumeNext) {final ActivityStack topStack = mStackSupervisor.getFocusedStack();if (!mService.isSleepingOrShuttingDownLocked()) {mStackSupervisor.resumeFocusedStackTopActivityLocked(topStack, prev, null);} else {......}}......
}

函数首先把prev和mPausingActivity变量清空,因为Launcher已经成Pause状态,暂时用不到这个变量了,resumeNext直接由上面传过来true,所以会调用ActivityStackSupervisor的resumeFocusedStackTopActivityLocked(),前面在。。地方见过这个方法,不过这里和之前传递的参数不同。

boolean resumeFocusedStackTopActivityLocked(ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {if (targetStack != null && isFocusedStack(targetStack)) {return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);}final ActivityRecord r = mFocusedStack.topRunningActivityLocked();if (r == null || r.state != RESUMED) {mFocusedStack.resumeTopActivityUncheckedLocked(null, null);}return false;
}

三个参数:targetStack–>topStack == null,target–>prev == null,targetOptions == null。

所以这里会直接执行mFocusedStack.resumeTopActivityUncheckedLocked(null, null);同前面一样进而执行ActivityStack.resumeTopActivityInnerLocked(null, null);

18. ActivityStack.resumeTopActivityInnerLocked()

路径:/frameworks/base/services/core/java/com/android/server/am/ActivityStack.java(line_2134)

private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {// Find the first activity that is not finishing.final ActivityRecord next = topRunningActivityLocked();// Remember how we'll process this pause/resume situation, and ensure// that the state is reset however we wind up proceeding.final boolean userLeaving = mStackSupervisor.mUserLeaving;mStackSupervisor.mUserLeaving = false;final TaskRecord prevTask = prev != null ? prev.task : null;next.delayedResume = false;// If the top activity is the resumed one, nothing to do.if (mResumedActivity == next && next.state == ActivityState.RESUMED) {......return false;}// If we are sleeping, and there is no resumed activity, and the top// activity is paused, well that is the state we want.if ((mService.mSleeping || mService.mShuttingDown)&& mLastPausedActivity == next && next.state == ActivityState.PAUSED) {......return false;}.......// We need to start pausing the current activity so the top one  // can be resumed...if (mResumedActivity != null) {......return true;}......if (next.app != null && next.app.thread != null) {......} else {......mStackSupervisor.startSpecificActivityLocked(next, true, true);}......
}

这个方法在之前详细介绍过,这里不再详细介绍,这里只说明和之前不同地方。

  • 我们知道,当前在堆栈顶端的Activity为我们即将要启动的MainActivity,这里通过调用topRunningActivityLocked()将它取回来,保存在next变量中。
  • 之前最后一个Resumed状态的Activity,即Launcher,到了这里已经处于Paused状态了,因此,mResumedActivity为null。
  • 最后一个处于Paused状态的Activity为Launcher,因此,这里的mLastPausedActivity就为Launcher。
  • 前面我们为MainActivity创建了ActivityRecord后,它的app域一直保持为null。

所以,它最终调用ActivityStackSupervisor的startSpecificActivityLocked(next,true,true)进行下一步操作。

19. ActivityStackSupervisor.startSpecificActivityLocked(next,true,true)

路径:/frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java(line_1389)

void startSpecificActivityLocked(ActivityRecord r,boolean andResume, boolean checkConfig) {// Is this activity's application already running?ProcessRecord app = mService.getProcessRecordLocked(r.processName,r.info.applicationInfo.uid, true);r.task.stack.setLaunchTime(r);if (app != null && app.thread != null) {try {if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0|| !"android".equals(r.info.packageName)) {app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode,mService.mProcessStats);}realStartActivityLocked(r, app, andResume, checkConfig);return;} catch (RemoteException e) {...}}mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,"activity", r.intent.getComponent(), false, false, true);
}

因为这是第一次启动当前Activity(MainActivity),所以获取到的app为null,不会执行if条件里的语句,直接执行mService.startProcessLocked()。

20. ActivityManagerService.startProcessLocked()

路径:/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java(line_3531)

final ProcessRecord startProcessLocked(String processName,ApplicationInfo info, boolean knownToBeDead, int intentFlags,String hostingType, ComponentName hostingName, boolean allowWhileBooting,boolean isolated, boolean keepIfLarge) {return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,null /* crashHandler */);
}

直接调用自己的重载方法startProcessLocked()(line_3541)

final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {...ProcessRecord app;if (!isolated) {app = getProcessRecordLocked(processName, info.uid, keepIfLarge);......} else {// If this is an isolated process, it can't re-use an existing process.app = null;}......String hostingNameStr = hostingName != null? hostingName.flattenToShortString() : null;if (app == null) {app = newProcessRecordLocked(info, processName, isolated, isolatedUid);if (app == null) {return null;}app.crashHandler = crashHandler;} else {// If this is a new package in the process, add the package to the listapp.addPackage(info.packageName, info.versionCode, mProcessStats);}// If the system is not ready yet, then hold off on starting this// process until it is.if (!mProcessesReady&& !isAllowedWhileBooting(info)&& !allowWhileBooting) {if (!mProcessesOnHold.contains(app)) {mProcessesOnHold.add(app);}if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,"System not ready, putting on hold: " + app);checkTime(startTime, "startProcess: returning with proc on hold");return app;}startProcessLocked(app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);return (app.pid != 0) ? app : null;
}

这里再次检查是否已经有以process + uid命名的进程存在,上面我们知道返回值app为null,因此,后面会调用newProcessRecordLocked()方法创建一个ProcessRecord存入app变量中,并添加在成员变量mProcessesOnHold中,最后,调用另一个重载的startProcessLocked()方法进一步操作(line_3670):

private final void startProcessLocked(ProcessRecord app, String hostingType,String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {long startTime = SystemClock.elapsedRealtime();if (app.pid > 0 && app.pid != MY_PID) {......app.setPid(0);}......try {try {final int userId = UserHandle.getUserId(app.uid);AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);} catch (RemoteException e) {throw e.rethrowAsRuntimeException();}int uid = app.uid;int[] gids = null;int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;if (!app.isolated) {int[] permGids = null;try {checkTime(startTime, "startProcess: getting gids from package manager");final IPackageManager pm = AppGlobals.getPackageManager();permGids = pm.getPackageGids(app.info.packageName,MATCH_DEBUG_TRIAGED_MISSING, app.userId);MountServiceInternal mountServiceInternal = LocalServices.getService(MountServiceInternal.class);mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,app.info.packageName);} catch (RemoteException e) {throw e.rethrowAsRuntimeException();}if (ArrayUtils.isEmpty(permGids)) {gids = new int[2];} else {gids = new int[permGids.length + 2];System.arraycopy(permGids, 0, gids, 2, permGids.length);}gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));}......int debugFlags = 0;......String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;if (requiredAbi == null) {requiredAbi = Build.SUPPORTED_ABIS[0];}String instructionSet = null;if (app.info.primaryCpuAbi != null) {instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);}app.gids = gids;app.requiredAbi = requiredAbi;app.instructionSet = instructionSet;boolean isActivityProcess = (entryPoint == null);if (entryPoint == null) entryPoint = "android.app.ActivityThread";checkTime(startTime, "startProcess: asking zygote to start proc");Process.ProcessStartResult startResult = Process.start(entryPoint,app.processName, uid, uid, gids, debugFlags, mountExternal,app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,app.info.dataDir, entryPointArgs);......} catch (RuntimeException e) {......}
}

首先对app里面的pid、uid、gids等变量赋值,最后请求Zygote来启动进程,这里调用Process.start接口来创建一个新的进程,新的进程会导入android.app.ActivityThread类(entryPoint变量),并且执行它的main函数,这就是为什么我们前面说每一个应用程序都有一个ActivityThread实例来对应的原因。

Zygote在什么地方调用ActivityThread.mian()?

大家有没有留意到平时自己写的APP出现crash时报错的堆栈信息刚开始都是这样的信息:

at android.os.Handler.handleCallback(Handler.java:836)
at android.os.Handler.dispatchMessage(Handler.java:103)
at android.os.Looper.loop(Looper.java:203)
at android.app.ActivityThread.main(ActivityThread.java:6251)
at java.lang.reflect.Method.invoke!(Native method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1073)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:934)

从堆栈中可以看出ZygoteInit的内部类MethodAndArgsCaller的run()方法使用反射机制(Method.invoke())调用ActivityThread.main()。

下面从ActivityThread.main()中继续分析Activity的启动。

21. ActivityThread.main()

路径:/frameworks/base/core/java/android/app/ActivityThread.java(line_6083)

public static void main(String[] args) {......Looper.prepareMainLooper();ActivityThread thread = new ActivityThread();thread.attach(false);......Looper.loop();...
}

main()方法中创建ActivityThread实例,并调用自身attach()方法,接下来就进入looper消息循环,直到进程结束。

attach()方法在当前类中(line_5930):

private void attach(boolean system) {sCurrentActivityThread = this;mSystemThread = system;if (!system) {......final IActivityManager mgr = ActivityManagerNative.getDefault();try {mgr.attachApplication(mAppThread);} catch (RemoteException ex) {throw ex.rethrowFromSystemServer();}// Watch for getting close to heap limit.......} else {......};......
}

这里又看到熟悉的身影,ActivityManagerNative.getDefault()正是之前遇见的ActivityManagerProxy类的实例,而ActivityManagerProxy又是AMS的远程接口类。肯定又是binder进程通信AMS。调用ActivityManagerProxy的attachApplication()方法。传入的参数是mAppThread,这是一个ApplicationThread类型的Binder对象,它的作用正是用来进行进程间通信的。

22. ActivityManagerNative.ActivityManagerProxy.attachApplication()

路径:/frameworks/base/core/java/android/app/ActivityManagerNative.java(line_3574)

public void attachApplication(IApplicationThread app) throws RemoteException
{Parcel data = Parcel.obtain();Parcel reply = Parcel.obtain();data.writeInterfaceToken(IActivityManager.descriptor);data.writeStrongBinder(app.asBinder());mRemote.transact(ATTACH_APPLICATION_TRANSACTION, data, reply, 0);reply.readException();data.recycle();reply.recycle();
}

binder进程通信调用AMS的attachApplication()方法。

23. ActivityManagerService.attachApplication()

路径:/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java(line_6667)

public final void attachApplication(IApplicationThread thread) {synchronized (this) {int callingPid = Binder.getCallingPid();final long origId = Binder.clearCallingIdentity();attachApplicationLocked(thread, callingPid);Binder.restoreCallingIdentity(origId);}
}

调用attachApplicationLocked()方法继续进行下一步,
这个方法在当前类中(line_6431)。

private final boolean attachApplicationLocked(IApplicationThread thread,int pid) {ProcessRecord app;if (pid != MY_PID && pid >= 0) {synchronized (mPidsSelfLocked) {app = mPidsSelfLocked.get(pid);}} else {app = null;}if (app == null) {......return false;}......final String processName = app.processName;try {AppDeathRecipient adr = new AppDeathRecipient(app, pid, thread);thread.asBinder().linkToDeath(adr, 0);app.deathRecipient = adr;} catch (RemoteException e) {......return false;}app.makeActive(thread, mProcessStats);app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;app.forcingToForeground = null;updateProcessForegroundLocked(app, false, false);app.hasShownUi = false;app.debugging = false;app.cached = false;app.killedByAm = false;......boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);......boolean badApp = false;boolean didSomething = false;// See if the top visible activity is waiting to run in this process...if (normalMode) {try {if (mStackSupervisor.attachApplicationLocked(app)) {didSomething = true;}} catch (Exception e) {......}}......return true;
}

之前已经创建了一个ProcessRecord,这里首先通过pid将它取回来,放在app变量中,然后对app的其它成员进行初始化。接着调用ActivityStackSupervisor的attachApplicationLocked()方法继续进行下一步。

24. ActivityStackSupervisor.attachApplicationLocked()

路径:/frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java(line_851)

boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {final String processName = app.processName;boolean didSomething = false;for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {final ActivityStack stack = stacks.get(stackNdx);if (!isFocusedStack(stack)) {continue;}ActivityRecord hr = stack.topRunningActivityLocked();if (hr != null) {if (hr.app == null && app.uid == hr.info.applicationInfo.uid&& processName.equals(hr.processName)) {try {if (realStartActivityLocked(hr, app, true, true)) {didSomething = true;}} catch (RemoteException e) {......}}}}}if (!didSomething) {ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);}return didSomething;
}

这里首先使用topRunningActivityLocked()方法取到栈顶Activity,即当前正在启动的Activity,存入hr变量中,前面我们也知道,hr.app一直是null,所以这里会执行realStartActivityLocked()进行真正的Activity启动操作。

25. ActivityStackSupervisor.realStartActivityLocked()

final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,boolean andResume, boolean checkConfig) throws RemoteException {......r.app = app;......int idx = app.activities.indexOf(r);if (idx < 0) {app.activities.add(r);}......final ActivityStack stack = task.stack;try {......List<ResultInfo> results = null;List<ReferrerIntent> newIntents = null;......if (andResume) {app.hasShownUi = true;app.pendingUiClean = true;}app.forceProcessStateUpTo(mService.mTopProcessState);app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),new Configuration(task.mOverrideConfig), r.compat, r.launchedFromPackage,task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results,newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo);......} catch (RemoteException e) {......}......return true;
}

这里最终通过app.thread进入到ApplicationThreadProxy的scheduleLaunchActivity函数中,注意,这里的第二个参数r.appToken,是一个ActivityRecord类型的Binder对象。

26. ApplicationThreadProxy.scheduleLaunchActivity()

路径:/frameworks/base/core/java/android/app/ApplicationThreadNative.java(line_849)

ApplicationThreadProxy是ApplicationThreadNative内部类。

public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,ActivityInfo info, Configuration curConfig, Configuration overrideConfig,CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,int procState, Bundle state, PersistableBundle persistentState,List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) throws RemoteException {Parcel data = Parcel.obtain();data.writeInterfaceToken(IApplicationThread.descriptor);intent.writeToParcel(data, 0);data.writeStrongBinder(token);data.writeInt(ident);info.writeToParcel(data, 0);curConfig.writeToParcel(data, 0);if (overrideConfig != null) {data.writeInt(1);overrideConfig.writeToParcel(data, 0);} else {data.writeInt(0);}compatInfo.writeToParcel(data, 0);data.writeString(referrer);data.writeStrongBinder(voiceInteractor != null ? voiceInteractor.asBinder() : null);data.writeInt(procState);data.writeBundle(state);data.writePersistableBundle(persistentState);data.writeTypedList(pendingResults);data.writeTypedList(pendingNewIntents);data.writeInt(notResumed ? 1 : 0);data.writeInt(isForward ? 1 : 0);if (profilerInfo != null) {data.writeInt(1);profilerInfo.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);} else {data.writeInt(0);}mRemote.transact(SCHEDULE_LAUNCH_ACTIVITY_TRANSACTION, data, null,IBinder.FLAG_ONEWAY);data.recycle();
}

这里又通过Binder进入到ApplicationThread的scheduleLaunchActivity()方法中。

27. ActivityThread.ApplicationThread.scheduleLaunchActivity()

路径:/frameworks/base/core/java/android/app/ActivityThread.java(line_713)

public final class ActivityThread {......private class ApplicationThread extends ApplicationThreadNative {......public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,ActivityInfo info, Configuration curConfig, Configuration overrideConfig,CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,int procState, Bundle state, PersistableBundle persistentState,List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {updateProcessState(procState, false);ActivityClientRecord r = new ActivityClientRecord();r.token = token;r.ident = ident;r.intent = intent;r.referrer = referrer;r.voiceInteractor = voiceInteractor;r.activityInfo = info;r.compatInfo = compatInfo;r.state = state;r.persistentState = persistentState;r.pendingResults = pendingResults;r.pendingIntents = pendingNewIntents;r.startsNotResumed = notResumed;r.isForward = isForward;r.profilerInfo = profilerInfo;r.overrideConfig = overrideConfig;updatePendingConfiguration(curConfig);sendMessage(H.LAUNCH_ACTIVITY, r);}......}......
}

这里将ApplicationThreadProxy.scheduleLaunchActivity()方法里的值通过binder传过来设置给新的实例r,并调用sendMessage()继续执行。

28. ActivityThread.sendMessage()

路径:/frameworks/base/core/java/android/app/ActivityThread.java(line_2482)

private void sendMessage(int what, Object obj) {sendMessage(what, obj, 0, 0, false);
}private void sendMessage(int what, Object obj, int arg1) {sendMessage(what, obj, arg1, 0, false);
}private void sendMessage(int what, Object obj, int arg1, int arg2) {sendMessage(what, obj, arg1, arg2, false);
}private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {if (DEBUG_MESSAGES) Slog.v(TAG, "SCHEDULE " + what + " " + mH.codeToString(what)+ ": " + arg1 + " / " + obj);Message msg = Message.obtain();msg.what = what;msg.obj = obj;msg.arg1 = arg1;msg.arg2 = arg2;if (async) {msg.setAsynchronous(true);}mH.sendMessage(msg);
}

调用ActivityThread的内部类H的sendMessage()方法。H继承Handler,所以这里sendMessage()的消息会在H里的handlerMessage()方法中被取出来,因为上面sendMessage时候设置int型变量为LAUNCH_ACTIVITY,所以会执行到下面代码:(line_1468)

public final class ActivityThread {......private class H extends Handler {......public void handleMessage(Message msg) {switch (msg.what) {case LAUNCH_ACTIVITY: {final ActivityClientRecord r = (ActivityClientRecord) msg.obj;r.packageInfo = getPackageInfoNoCheck(r.activityInfo.applicationInfo, r.compatInfo);handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");} break;......}......}......}......
}

这里最后调用ActivityThread类的handleLaunchActivity()进一步处理。

29. ActivityThread.handleLaunchActivity()

路径:/frameworks/base/core/java/android/app/ActivityThread.java(line_2706)

private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {// If we are getting ready to gc after going to the background, well// we are back active so skip it.......Activity a = performLaunchActivity(r, customIntent);if (a != null) {r.createdConfig = new Configuration(mConfiguration);reportSizeConfigurations(r);Bundle oldState = r.state;handleResumeActivity(r.token, false, r.isForward,!r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);......} else {......}
}

这里首先调用performLaunchActivity()来加载启动的这个Activity类,然后调用它的onCreate(),最后回到handleLaunchActivity()时,再调用handleResumeActivity()来使这个Activity进入Resumed状态,即会调用这个Activity的onResume(),这是遵循Activity的生命周期的。下面详细分析一下performLaunchActivity()方法。

30. ActivityThread.performLaunchActivity

路径:/frameworks/base/core/java/android/app/ActivityThread.java(line_2533)

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {//@{{获取Activity的package和component信息ActivityInfo aInfo = r.activityInfo;if (r.packageInfo == null) {r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,Context.CONTEXT_INCLUDE_CODE);}ComponentName component = r.intent.getComponent();if (component == null) {component = r.intent.resolveActivity(mInitialApplication.getPackageManager());r.intent.setComponent(component);}if (r.activityInfo.targetActivity != null) {component = new ComponentName(r.activityInfo.packageName,r.activityInfo.targetActivity);}//}}Activity activity = null;try {//通过ClassLoader将要启动的Activity所在的类加载进来java.lang.ClassLoader cl = r.packageInfo.getClassLoader();activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);StrictMode.incrementExpectedActivityCount(activity.getClass());r.intent.setExtrasClassLoader(cl);r.intent.prepareToEnterProcess();if (r.state != null) {r.state.setClassLoader(cl);}} catch (Exception e) {......}try {//通过AndroidManifest.xml中的<application>标签创建Application对象Application app = r.packageInfo.makeApplication(false, mInstrumentation);if (activity != null) {//创建对应当前Activity的context对象Context appContext = createBaseContextForActivity(r, activity);CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());Configuration config = new Configuration(mCompatConfiguration);if (r.overrideConfig != null) {config.updateFrom(r.overrideConfig);}Window window = null;if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {window = r.mPendingRemoveWindow;r.mPendingRemoveWindow = null;r.mPendingRemoveWindowManager = null;}//将上面的创建好的context对象设置到Activity中去activity.attach(appContext, this, getInstrumentation(), r.token,r.ident, app, r.intent, r.activityInfo, title, r.parent,r.embeddedID, r.lastNonConfigurationInstances, config,r.referrer, r.voiceInteractor, window);if (customIntent != null) {activity.mIntent = customIntent;}r.lastNonConfigurationInstances = null;activity.mStartedActivity = false;int theme = r.activityInfo.getThemeResource();if (theme != 0) {activity.setTheme(theme);}//通过Instrumentation对象调用Activity的onCreate()方法activity.mCalled = false;if (r.isPersistable()) {mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);} else {mInstrumentation.callActivityOnCreate(activity, r.state);}......r.activity = activity;r.stopped = true;if (!r.activity.mFinished) {activity.performStart();r.stopped = false;}if (!r.activity.mFinished) {if (r.isPersistable()) {if (r.state != null || r.persistentState != null) {mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,r.persistentState);}} else if (r.state != null) {mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);}}if (!r.activity.mFinished) {activity.mCalled = false;if (r.isPersistable()) {mInstrumentation.callActivityOnPostCreate(activity, r.state,r.persistentState);} else {mInstrumentation.callActivityOnPostCreate(activity, r.state);}......}}r.paused = true;mActivities.put(r.token, r);} catch (SuperNotCalledException e) {throw e;} catch (Exception e) {......}return activity;
}

如上注释所述,这个方法主要内容可以总结如下几点:

  1. 获取要启动Activity的package和component信息;
  2. 通过ClassLoader加载启动Activity所在的类并实例化为Activity类型;
  3. 通过AndroidManifest.xml中的标签创建Application对象;
  4. 创建对应Activity的context对象(上下文对象);
  5. 调用activity.attach()将上面创建的context对象设置到Activity中;
  6. 通过Instrumentation.callActivityOnCreate()间接调用Activity的onCreate()方法,为什么不直接调呢?Instrumentation这个类在刚开始的时候见过,说过它是一种控制和监管Activity和系统之间的交互的“管家”(见前面对该词解释)。

最后进入到要启动MainActivity里的onCreate()方法,这样整个application都启动起来了。

总结一下

整个启动流程设计源码很多,但是可以发现有几处binder进程通信,所以可以总结为下面6步:

  1. 1-4:Launcher通过Binder进程间通信机制通知ActivityManagerService,它要启动一个Activity,AMS创建相应的ActivityRecord、ActivityStack等;
  2. 5-12:ActivityManagerService通过Binder进程间通信机制通知Launcher进入Paused状态;
  3. 13-14:Launcher通过Binder进程间通信机制通知ActivityManagerService,它已经进入Paused状态。
  4. 15-22:ActivityManagerService就调用Zygote创建一个新的进程,并且启动一个ActivityThread实例,将要启动的Activity就是运行在这个ActivityThread实例中;接着ActivityThread通过Binder进程间通信机制通知ActivityManagerService进程已启动,请求启动Activity;
  5. 23-26:ActivityManagerService通过Binder进程间通信机制通知ActivityThread,现在一切准备就绪,它可以真正执行Activity的启动操作了。
  6. 27-30:ActivityThread执行启动操作,启动整个application。

Activity启动流程源码分析(基于Android N)相关推荐

  1. Activity启动流程源码分析-浅析生命周期函数

    源码分析 接着上一篇 Activity启动流程源码分析-setContentView源码阅读 的讲解,本节介绍一下Activity的生命周期函数何时被调用 要看Activity的生命周期函数何时被调用 ...

  2. SpringBoot2 | SpringBoot启动流程源码分析(一)

    首页 博客 专栏·视频 下载 论坛 问答 代码 直播 能力认证 高校 会员中心 收藏 动态 消息 创作中心 SpringBoot2 | SpringBoot启动流程源码分析(一) 置顶 张书康 201 ...

  3. Activity启动过程源码分析

    老罗的Android系统源码分析讲的很不错,网上有很不同层面多源码分析.了解细节,还是自己看源码最直接.个人并没有透彻的研究过Android系统,这一系列的博客就当是读Android源码笔记了.有不对 ...

  4. DataNode启动流程源码分析

    我们都知道在Hadoop hdfs文件系统中,Datanode是负责hdfs文件对应的数据块存储管理的组件,其会在启动时向NameNode汇报其上拥有的数据块,以及周期性心跳并接收来自NameNode ...

  5. SpringBoot配置外部Tomcat项目启动流程源码分析(下)

    前言 SpringBoot应用默认以Jar包方式并且使用内置Servlet容器(默认Tomcat),该种方式虽然简单但是默认不支持JSP并且优化容器比较复杂.故而我们可以使用习惯的外置Tomcat方式 ...

  6. Spark On YARN启动流程源码分析

    1.spark-submit入口介绍 一般的spark作业都是通过命令行spark-submit相关的指令来进行提交,使用--master yarn来指定提交到对应的yarn集群上,如下: ./bin ...

  7. Android11 SystemUI启动流程源码分析(一)——SystemUIApplication的创建

    Manifest入口 <applicationandroid:name=".SystemUIApplication"... ...android:appComponentFa ...

  8. Android系统默认Home应用程序(Launcher)的启动过程源码分析

    在前面一篇文章中,我们分析了Android系统在启动时安装应用程序的过程,这些应用程序安装好之后,还须要有一个Home应用程序来负责把它们在桌面上展示出来,在Android系统中,这个默认的Home应 ...

  9. Android音频框架之二 用户录音启动流程源码走读

    前言 此篇是对<Android音频框架之一 详解audioPolicy流程及HAL驱动加载>的延续,此系列博文是记录在Android7.1系统即以后版本实现 内录音功能. 当用户使用 Au ...

最新文章

  1. JDK8:使用Optional进行变量判空、集合遍历
  2. java016.集合
  3. 我是如何阅读编程书的
  4. java中的访问修饰符 (2013-10-11-163 写的日志迁移
  5. 【视频】vue表单提交
  6. 参数等效模型可以用于_干货分享电池单体产热特性及热模型标定分析(2)
  7. 推荐40个优秀的免费CSS工具
  8. java原生怎么发请求,java原生http请求post
  9. php文本框输入内容过滤,为什么没能过滤掉文本框输入的所有反斜杠?
  10. 协同过滤推荐算法总结
  11. JMP软件在六西格玛项目管理中高阶应用(五)
  12. 实验方法怎么写_作文《你真好》怎么写?语文课本里找方法,附审题、写作思路...
  13. Java - Certificate has been revoked
  14. aecmap快捷键_ARCMAP快捷键总结
  15. Mac安装Node-sass报错 warning: loop variable ‘numerator‘ creates a copy from type ‘const std::string
  16. EKL日志平台架构概括
  17. 二进制与十进制转换器
  18. 论文阅读—图像分割方法综述(三)(arXiv:[cs:cv]20200410)
  19. Sklearn 损失函数如何应用到_菜鸟学机器学习,Sklearn库主要模块功能简介
  20. Vue -- vue-router(路由)的基本使用

热门文章

  1. 跑胡子c语言算法,跑胡子胡牌算法
  2. surfaceflinger分析
  3. 想跨界的安防企业,跨界之前你可看准了
  4. 5.新浪微博Swift项目第五天
  5. 世界机器人大赛_体验未来黑科技!BCI脑控机器人亮相2019世界机器人大赛总决赛...
  6. python lcut精确分词_Python jieba库分词模式实例用法
  7. (转)利用libcurl获取新浪股票接口, ubuntu和openwrt实验成功(三)
  8. java的finalize_Java中的finalize()方法
  9. SQL学习十二、插入数据
  10. C++基础——C++ make_pair用法