参考文献:刘望舒《Android进阶解密》

前言

​ 看了数篇分析Activity启动流程的文章,但是自从看了《Android进阶解密》关于Activity启动流程的分析,我就放弃了自己撸一遍的念头。因为书里关于这部分的分析比较详细。这里记录一下书中关于Activity的启动流程。加深一下印象,便于以后温习查看。
Activity的启动过程分为两种,一种是根Activity的启动过程,可以认为是初次点击桌面的应用图标,启动Manifest中注册的作为应用的启动页面的Activity。根Activity的启动过程也可以理解为应用程序的启动过程。另一种就是普通Activity的启动过程,也就是根Activity以外的Activity的启动过程。这两种Activity的启动过程有重叠的部分,但是根Activity一般理解为应用程序的启动过程,更具有指导意义。因此本文就根Activity的启动过程进行分析。

谈到Activity的启动流程就绕不开ActivityManagerService(简称AMS),它主要负责四大组件的启动、切换、调度以及进程的管理,是Android中最核心的服务,参与了所有应用程序的启动管理。Activity的启动流程围绕AMS,可以大致分为3个部分:

  • Launcher请求AMS的过程
  • AMS到ApplicationThread的调用过程
  • ActivityThread启动Activity的过程

下面就针对这3个部分逐一进行分析。

1.Launcher请求AMS的过程

该过程的时序图如下:


当我们点击桌面的应用快捷图标时,就会调用Launcher的startActivitySafely方法:

public boolean startActivitySafely(View v, Intent intent, ItemInfo item) {...// Prepare intent// 注释1intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);...// Could be launching some bookkeeping activity// 注释2startActivity(intent, optsBundle);...
}

对于不太需要关注的代码省略了,主要是走调用流程,对关键代码进行分析,在注释1处将Flag设置为Intent.FLAG_ACTIVITY_NEW_TASK,这样根Activity会在新的任务栈中启动。在注释2处调用startActivity方法,这个方法在Activity中实现,Activity中startActivity方法有好几种重载方式,但它们最终都会调用startActivityForResult方法:

public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,@Nullable Bundle options) {// 注释1if (mParent == null) {options = transferSpringboardActivityOptions(options);// 注释2Instrumentation.ActivityResult ar =mInstrumentation.execStartActivity(this, mMainThread.getApplicationThread(), mToken, this,intent, requestCode, options);...} else {...}}

注释1处的mParent是Activity类型的,表示当前Activity的父类,因为目前根Activity还没有创建出来,因此mParent==null成立,执行注释2处的逻辑,调用Instrumentation的execStartActivity方法,Instrumentation主要是用来监控应用程序和系统的交互,execStartActivity方法代码如下:

public ActivityResult execStartActivity(Context who, IBinder contextThread, IBinder token, Activity target,Intent intent, int requestCode, Bundle options) {...try {intent.migrateExtraStreamToClipData();intent.prepareToLeaveProcess(who);// 注释1int result = ActivityManager.getService().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;}

核心逻辑就是注释1的代码,首先调用ActivityManager的getService方法来获取AMS的代理对象,接着调用startActivity方法。我们先进入ActivityManager的getService方法:

public static IActivityManager getService() {return IActivityManagerSingleton.get();}private static final Singleton<IActivityManager> IActivityManagerSingleton =new Singleton<IActivityManager>() {@Overrideprotected IActivityManager create() {// 注释1final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);// 注释2final IActivityManager am = IActivityManager.Stub.asInterface(b);return am;}};

getService方法调用了IActivityManagerSingleton的get方法,看一下Singleton代码

public abstract class Singleton<T> {private T mInstance;protected abstract T create();public final T get() {synchronized (this) {if (mInstance == null) {mInstance = create();}return mInstance;}}
}

不难发现IActivityManagerSingleton的get方法,会调用create方法,在注释1处得到IBinder类型的AMS引用,接着在注释2处将它转化成IActivityManager类型的对象,即AMS的代理对象,这段代码采用的是AIDL,IActivityManager.java类是由AIDL工具在编译时自动生成的。AMS继承IActivityManager.Stub类并实现相关方法。通过这个代理对象和AMS(AMS所在的进程为SystemServer系统服务进程)进行跨进程通信,如果你对Binder机制有一定的认识,这里就比较好理解。如果还不太熟悉Binder机制,强烈建议一定要补一下,要不然分析源码总会一知半解的。需要注意的Android8.0之前并没有采用AIDL,是用AMS的代理对象ActivityManagerProxy来与AMS进行跨进程通信的。Android8.0去除了ActivityManagerNative的内部类ActivityManagerProxy,代替它的是IActivityManager,它就是AMS的代理对象。经过上面的分析,我们知道execActivity方法最终调用的是AMS的startActivity方法。补充一句,这里就由Launcher进程经过一系列调用到了SystemServer进程,可以简单概括为下图:

2.AMS到ApplicationThread的调用过程

Launcher请求AMS后,代码逻辑进入AMS中,接着是AMS到ApplicationThread的调用流程,时序图如下:

AMS的startActivity方法如下:

@Override
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());
}

AMS的startActivity方法中返回了startActivityAsUser方法,可以发现startActivityAsUser方法比startActivity方法多了一个参数UserHandle.getCallingUserId(),这个方法会获得调用者的UserId,AMS根据这个UserId来确定调用者的权限。下面进入startActivityAsUser方法:

@Override
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) {// 注释1// 判断调用者进程是否被隔离enforceNotIsolatedCaller("startActivity");// 注释2// 检查调用者的权限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,"startActivityAsUser");
}

在注释1处判读调用者进程是否隔离,如果没被隔离则抛出SecurityException异常,在注释2处检查调用者是否有权限,如果没有权限也会抛出SecurityException异常。最后调用了ActivityStarter的startActivityMayWait方法,参数要比startActivityAsUser多几个,需要注意的是倒数第二个参数类型为TaskRecord,代表启动的Activity所在的栈,最后一个参数"startActivityAsUser"代表启动的理由,接下来进入startActivityMayWait方法:

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) {...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;}
}

ActivityStarter是Android7.0中新加入的类,它是加载Activity的控制类,会收集所有的逻辑来决定如何将Intent和Flags转换为Activity,并将Activity和Task以及Stack相关联。ActivityStarter的startActivityMayWait方法调用了startActivityLocked方法:

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, String reason) {// 注释1// 判断启动if (TextUtils.isEmpty(reason)) {throw new IllegalArgumentException("Need to specify a reason.");}...mLastStartReason = reason;mLastStartActivityTimeMs = System.currentTimeMillis();mLastStartActivityRecord[0] = null;// 注释2mLastStartActivityResult = startActivity(caller, intent, ephemeralIntent, resolvedType,aInfo, rInfo, voiceSession, voiceInteractor, resultTo,resultWho, requestCode,callingPid, callingUid, callingPackage, realCallingPid,realCallingUid,startFlags,options,ignoreTargetSecurity,componentSpecified,mLastStartActivityRecord,container, inTask);if (outActivity != null) {// mLastStartActivityRecord[0] is set in the call to startActivity above.outActivity[0] = mLastStartActivityRecord[0];}return mLastStartActivityResult;
}

在注释1处判断启动的理由不为空,如果为空则抛出IllegalArgumentException异常。紧接着在注释2处又调用了startActivity方法:

/** DO NOT call this method directly. Use {@link #startActivityLocked} instead. */
private int startActivity(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;// Pull the optional Ephemeral Installer-only bundle out of the options early.final Bundle verificationBundle= options != null ? options.popAppVerificationBundle() : null;ProcessRecord callerApp = null;// 注释1// caller为IApplicationThread类型if (caller != null) {// 注释2// 得到Launcher进程callerApp = mService.getRecordForAppLocked(caller);if (callerApp != null) {// 获取Launcher进程的pid和uidcallingPid = callerApp.pid;callingUid = callerApp.info.uid;} else {Slog.w(TAG, "Unable to find app for caller " + caller+ " (pid=" + callingPid + ") when starting: "+ intent.toString());err = ActivityManager.START_PERMISSION_DENIED;}}...// 注释3// 创建即将要启动的Activity的描述类ActivityRecordActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(),resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null,mSupervisor, container, options, sourceRecord);if (outActivity != null) {// 注释4outActivity[0] = r;}...doPendingActivityLaunchesLocked(false);// 注释5return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags,true,options, inTask, outActivity);}

ActivityStarter的startActivity方法逻辑比较多,这里列出部分需要注意的代码。在注释1处判断IApplicationThread类型的caller是否为null,这个caller是方法调用一路传过来的,指向的是Launcher所在的应用程序进程的ApplicationThread对象,在注释2处调用AMS的getRecordForAppLocked方法得到的是代表Launcher进程的callApp对象,它是ProcessRecord类型的,ProcessRecord用于描述一个应用程序进程。同样的,ActivityRecord用于描述一个Activity,用来记录一个Activity的所有信息。接下来创建ActivityRecord,用于描述将要启动的Activity,并在注释4处将创建的ActivityRecord赋值给ActivityRecord[]类型的outActivity,这个outActivity会作为注释5处的startActivity方法的参数传递下去。

private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,ActivityRecord[] outActivity) {int result = START_CANCELED;try {mService.mWindowManager.deferSurfaceLayout();// 注释1result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,startFlags, doResume, options, inTask, outActivity);} ...return result;
}

startActivity方法接着调用了startActivityUnchecked方法:

private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,ActivityRecord[] outActivity) {...// 注释1if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask&& (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {newTask = true;// 注释2// 创建新的TaskRecordresult = setTaskFromReuseOrCreateNewTask(taskToAffiliate, preferredLaunchStackId, topStack);} else if (mSourceRecord != null) {result = setTaskFromSourceRecord();} else if (mInTask != null) {result = setTaskFromInTask();} else {// This not being started from an existing activity,// and not part of a new task...// just put it in the top task, though these days this case should never happen.setTaskToCurrentTopOrCreateNewTask();}...if (mDoResume) {final ActivityRecord topTaskActivity =mStartActivity.getTask().topRunningActivityLocked();if (!mTargetStack.isFocusable()|| (topTaskActivity != null && topTaskActivity.mTaskOverlay&& mStartActivity != topTaskActivity)) {...} else {if (mTargetStack.isFocusable()&&!mSupervisor.isFocusedStack(mTargetStack)) {mTargetStack.moveToFront("startActivityUnchecked");}// 注释3mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack,mStartActivity,mOptions);}} else {mTargetStack.addRecentActivityLocked(mStartActivity);}...}

startActivityUnchecked方法主要处理与栈管理相关的逻辑。在前面Launcher的startActivitySafely中,将Intent的Flag设置为FLAG_ACTIVITY_NEW_TASK,这样注释1处的条件判断就会满足,接着执行注释2处的setTaskFromReuseOrCreateNewTask方法内部会创建一个新的Activity任务栈。在注释3处会调用ActivityStackSupervisor的resumeFocusedStackTopActivityLocked方法:

boolean resumeFocusedStackTopActivityLocked(ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions){if (targetStack != null && isFocusedStack(targetStack)) {return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);}// 注释1// 获取要启动的Activity所在的栈的栈顶的不是处于停止状态的ActivityRecordfinal ActivityRecord r = mFocusedStack.topRunningActivityLocked();// 注释2if (r == null || r.state != RESUMED) {// 注释3mFocusedStack.resumeTopActivityUncheckedLocked(null, null);} else if (r.state == RESUMED) {// Kick off any lingering app transitions form the MoveTaskToFront operation.mFocusedStack.executeAppTransition(targetOptions);}return false;
}

注释1处调用ActivityStack的topRunningActivityLocked方法获取要启动的Activity所在栈的栈顶并且不是停止状态的ActivityRecord。在注释2处,如果ActivityRecord不为null,或者要启动的Activity的状态不是RESUMED状态,就会调用注释3处的ActivityStack的resumeTopActivityUncheckedLocked方法,对于即将启动的Activity,注释2处条件判断是肯定满足的,接下来查看ActivityStack的resumeTopActivityUnchecked方法:

boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {if (mStackSupervisor.inResumeTopActivity) {// Don't even start recursing.return false;}boolean result = false;try {// Protect against recursion.mStackSupervisor.inResumeTopActivity = true;// 注释1result = resumeTopActivityInnerLocked(prev, options);} ...
}

紧接着查看注释1处的ActivityStack的resumeTopActivityInnerLocked方法:

private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) { ...// 注释1mStackSupervisor.startSpecificActivityLocked(next, true, true);}if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();return true;}

接着进入注释1处,ActivityStackSupervisor的startSpecificActivityLocked方法

void startSpecificActivityLocked(ActivityRecord r,boolean andResume, boolean checkConfig) {// Is this activity's application already running?// 注释1// 获取即将启动的Activity的所在的应用进程ProcessRecord app = mService.getProcessRecordLocked(r.processName,r.info.applicationInfo.uid, true);r.getStack().setLaunchTime(r);// 注释2// 判断要启动的Activity所在的应用程序进程如果已经运行的话,就会调用注释3处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);}// 注释3// 这个方法第二个参数是代表要启动的Activity所在的应用程序进程的ProcessRecordrealStartActivityLocked(r, app, andResume, checkConfig);return;} catch (RemoteException e) {Slog.w(TAG, "Exception when starting activity "+ r.intent.getComponent().flattenToShortString(), e);}// If a dead object exception was thrown -- fall through to// restart the application.}mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,"activity", r.intent.getComponent(), false, false, true);}

​ 在注释1处获取即将启动的Activity所在的应用程序进程,在注释2处判断要启动的Activity所在的应用程序进程如果已经运行的话,就会调用注释3处的realStartActivityLocked方法,这个方法的第二个参数是代表要启动的Activity所在的应用程序进程的ProcessRecord。接下来进入realStartActivityLocked方法:

final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,boolean andResume, boolean checkConfig) throws RemoteException {...// 注释1// app是ProcessRecord类型的,thread是IApplicationThread类型的app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,System.identityHashCode(r), r.info,mergedConfiguration.getGlobalConfiguration(),mergedConfiguration.getOverrideConfiguration(), r.compat,r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,r.persistentState, results, newIntents, !andResume,mService.isNextTransitionForward(), profilerInfo);...return true;
}

​ 注释1处的app.thread指的是IApplicationThread,其中ApplicationThread继承了IApplicationThread.Stub。app指的是传入的要启动的Activity所在的应用程序进程,因此这段代码指的就是要在目标应用程序进程启动Activity。当前代码逻辑运行在AMS所在的进程(SystemServer系统服务进程)中,通过ApplicationThread来与应用程序进程进程Binder通信(跨进程通信),也就是说ApplicationThread是AMS和应用程序进程的通信桥梁

3.ActivityThread启动Activity的过程

通过前面的分析,我们知道代码逻辑目前运行到应用程序进程中,ActivityThread启动Activity过程时序图如下:

接着查看ApplicationThread的scheduleLaunchActivity方法,ApplicationThread是ActivityThread的内部类,ActivityThread负责管理当前应用程序进程的主线程,scheduleLaunchActivity方法代码如下:

@Override
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);// 此处的r就是保存要启动activity的信息,作为参数通过sendMessage发送出去ActivityClientRecord r = new ActivityClientRecord();r.token = token;r.ident = ident;r.intent = intent;r.referrer = referrer;...updatePendingConfiguration(curConfig);sendMessage(H.LAUNCH_ACTIVITY, r);
}

​ scheduleLaunchActivity方法将启动Activity的参数封装成ActivityClientRecord。sendMessage方法向H类发送类型为LAUNCH_ACTIVITY的消息,并将ActivityClientRecord传递出去,sendMessage方法有多个重载,最终调用的sendMessage方法如下:

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);
}

​ 这里的mH指的是H,它是ActivityThread的内部类并继承Handler,是应用程序进程中主线程的消息管理类。因为ApplicationThread是一个Binder,它的调用逻辑运行在Binder线程池(子线程)中,所以这里需要用H将代码的逻辑切换到主线程中。H类中处理消息的handleMessage方法如下:

public void handleMessage(Message msg) {if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));switch (msg.what) {case LAUNCH_ACTIVITY: {Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");// 注释1// 取出之前保存的要启动的Activity的信息// 这些信息封装在ActivityClientRecord这个类中final ActivityClientRecord r = (ActivityClientRecord) msg.obj;// 注释2// pachageinfo 指的是LoadedApkr.packageInfo = getPackageInfoNoCheck(r.activityInfo.applicationInfo, r.compatInfo);handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);} break;case RELAUNCH_ACTIVITY: {Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityRestart");ActivityClientRecord r = (ActivityClientRecord)msg.obj;handleRelaunchActivity(r);Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);} break;...}...
}

查看H类中handleMessage方法中对LAUNCH_ACTIVITY的处理,在注释1处将传过来的msg的成员变量obj转换为ActivityClientRecord。在注释2处通过getPackageInfoNoCheck方法获得LoadedApk类型的对象并赋值给ActivityClientRecord的成员变量packageInfo。应用程序要启动Activity时需要将该Activity所属的APK加载进来,而LoadedApk就是用来描述已加载的APK文件的。接着调用handleLaunchActivity方法:

private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason){...   // Initialize before creating the activityWindowManagerGlobal.initialize();// 注释1// 启动ActivityActivity a = performLaunchActivity(r, customIntent);if (a != null) {r.createdConfig = new Configuration(mConfiguration);reportSizeConfigurations(r);Bundle oldState = r.state;// 注释2// 将Activity的状态置为ResumehandleResumeActivity(r.token, false, r.isForward,!r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);if (!r.activity.mFinished && r.startsNotResumed) {performPauseActivityIfNeeded(r, reason);if (r.isPreHoneycomb()) {r.state = oldState;}}} else {// If there was an error, for any reason, tell the activity manager to stop us.try {// 注释3// 停止Activity启动ActivityManager.getService().finishActivity(r.token, Activity.RESULT_CANCELED, null,Activity.DONT_FINISH_TASK_WITH_ACTIVITY);} catch (RemoteException ex) {throw ex.rethrowFromSystemServer();}}
}

​ 注释1处的performLaunchActivity方法用来启动Activity,注释2处的代码用来将Activity的状态设置为Resume,如果该Activity为null,就会执行注释3处的逻辑,通知AMS停止启动Activity,接下来进入performLaunchActivity:

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) // 注释1// 获取ActivityInfo类ActivityInfo aInfo = r.activityInfo;if (r.packageInfo == null) {// 注释2// 获取APK文件的描述类r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,Context.CONTEXT_INCLUDE_CODE);}// 注释3// 获取要启动Activity的ComponentName类,它保存了该Activity的包名和类名ComponentName component = r.intent.getComponent();...// 注释4// 创建要启动Activity的上下文ContextImpl appContext = createBaseContextForActivity(r);Activity activity = null;try {java.lang.ClassLoader cl = appContext.getClassLoader();// 注释5// 通过类加载器来创建要启动的Activity的实例activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);...}} catch (Exception e) {...}try {// 注释6// 创建ApplicationApplication app = r.packageInfo.makeApplication(false, mInstrumentation);...if (activity != null) {...// 注释7// 初始化Activityactivity.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, r.configCallback);...if (r.isPersistable()) {// 注释8// 顾名思义下一步就是去调用Activity的onCreate方法mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);} else {mInstrumentation.callActivityOnCreate(activity, r.state);}...r.paused = true;mActivities.put(r.token, r);} catch (SuperNotCalledException e) {throw e;} catch (Exception e) {...}return activity;}

​ 在注释1处获取ActivityInfo,用于存储代码以及AndroidManifest设置的Activity和Receiver节点信息,比如Activity的theme和launchMode。在注释2处获取APK文件的描述类LoadedApk。在注释3处获取要启动的Activity的ComponentName类,在该类中保存了Activity的包名和类名。注释4处用来创建要启动Activity的上下文环境。注释5处根据ComponentName中存储的Activity类名,用类加载器来创建该Activity的实例。注释6处用来创建Application,makeApplication方法内部会调用Application的onCreate方法。注释7处调用Activity的attach方法初始化Activity,在attach方法中会创建Window对象(PhoneWindow)并与Activity自身进行关联。在注释8处调用Instrumentation的callActivityOnCreate方法:

public void callActivityOnCreate(Activity activity, Bundle icicle,PersistableBundle persistentState) {prePerformCreate(activity);activity.performCreate(icicle, persistentState);postPerformCreate(activity);
}

进入activity的performCreate方法:

final void performCreate(Bundle icicle, PersistableBundle persistentState) {restoreHasCurrentPermissionRequest(icicle);// 注释1// 正式进入Activity的生命周期方法onCreate(icicle, persistentState);mActivityTransitionState.readState(icicle);performCreateCommon();
}

​ 如注释1处代码所示,正式进入Activity的生命周期方法,根Activity的启动流程大致分析完了,下面对大致流程进行小结一下。

4.总结

根Activity的启动过程涉及4个进程,分别是Launcher进程、AMS所在进程(SystemServer进程)、Zygote进程、应用程序进程,首先Launcher进程向AMS请求创建根Activity,AMS会判断根Activity所需要的应用程序进程是否存在并启动,如果不存储就会请求Zygote进程创建应用程序进程。应用程序进程启动后,AMS会请求应用程序进程启动根Activity。大致流程如下:

  • Launcher—>AMS: Instrumentation主要用来监控应用程序和系统的交互,过渡调用它的execStartActivity方法,在该方法中获取AMS的代理对象,调用startActivity,即binder通信,跨进程进入AMS所在进程SystemServer,调用AMS的startActivity方法

  • AMS—>ApplicationThread: 这个过程涉及的类和方法相对较多,但主要完成下面三件事
    ①综合处理 launchMode 和 Intent 中的 Flag 标志位,并根据处理结果生成一个目标 Activity B 的对象(ActivityRecord)。
    ②判断是否需要为目标 Activity B 创建一个新的进程(ProcessRecord)、新的任务栈(TaskRecord)。
    ③获取ApplicationThread的代理对象,通过binder通信,跨进程到应用程序进程,去调用scheduleLaunchActivity去启动根Activity。

  • ActivityThread启动Activity的过程
    scheduleLaunchActivity通过sendMessage向H类发送类型为LAUNCH_ACTIVITY的消息,H类的handleMessage方法,处理消息,调用ActivityThread的handleLaunchActivity,接着调用performLaunchActivity,又回到应用程序与系统交互的监控类Instrumentation,调用它的callActivityOnCreate方法,接着调用Activity的performCreate方法和onCreate方法,正式进入Activity的生命周期方法,启动Activity

Activity的启动流程分析与总结相关推荐

  1. Android Activity的启动流程分析:以Launcher启动一个Activity为例,分析应用进程的创建、Activity的启动,以及他们和AMS之间的交互

    文章目录 一. Step1 - Step 11:Launcher通过Binder进程间通信机制通知ActivityManagerService,它要启动一个Activity: Step 1. Laun ...

  2. 文化袁探索专栏——Activity|Application启动流程

    文化袁探索专栏--Activity.Window和View三者间关系 文化袁探索专栏--View三大流程#Measure 文化袁探索专栏--View三大流程#Layout 文化袁探索专栏--消息分发机 ...

  3. c++builder启动了怎么停止_App 竟然是这样跑起来的 —— Android App/Activity 启动流程分析...

    在我的上一篇文章: AJie:按下电源键后竟然发生了这一幕 -- Android 系统启动流程分析​zhuanlan.zhihu.com 我们分析了系统在开机以后的一系列行为,其中最后一阶段 AMS( ...

  4. Cocos2d-x3.3RC0的Android编译Activity启动流程分析

    http://www.itnose.net/detail/6142692.html 本文将从引擎源码Jni分析Cocos2d-x3.3RC0的Android Activity的启动流程,下面是详细分析 ...

  5. 【拒绝一问就懵】之Activity的启动流程

    背景介绍 从事开发到了一定阶段,想要提高就必须搞明白系统的一些工作原理.为什么?因为只有明白了这些,你才能针对平台的特性写出优质的代码.当遇到棘手的问题时,你才能更快速的结合系统原理去寻找最优解决方案 ...

  6. Android 四大组件之——Acitivity(三) 深入了解Activity的启动流程

    上图为整个Activity的启动流程 接下来我们大概分析 在我们的Android系统中,应用程序是由Launcher这个应用启动起来的.当我们安装好应用程序之后,就会在Launcher的界面上生成一个 ...

  7. Activity的启动流程

    Activity的启动流程 努力工作 自己平时工作接触的frameworks代码比较多,但真正理解的很有限,一直在努力分析..我主要还是用补丁的形式来看 core/java/android/app/A ...

  8. Android M应用启动流程分析

    更新: 2016-10-29:更新handleBindApplication部分. 我这个版本的原则是,有话则长,无话则短. 以下分析基于6.0.1_r10版本. 先看一张大图: 1. 桌面的onCl ...

  9. Android系统开机到Launcher启动流程分析

    本文基于Android10.0的源码. 由于google团队在对framework层代码进行大量重构,所以代码变动还是挺大的. 常见基础问题: SystemServer系统服务进程是如何创建的?Lau ...

  10. android 开机向导加载过程,开机向导启动流程分析

    开机向导启动流程 首先来看Android启动流程: 1.Bootloader(系统启动加载器,将Linux加载到RAM): 2.Kernel 3.init进程 4.Zygote(Zygote进程是整个 ...

最新文章

  1. react select默认选项_reactjs – 如何为Picker提供默认的“Please select …”选项?
  2. h.265编码库x265实例
  3. 理解ArcIMS投影元素
  4. 怎么通过邮箱发超大附件?介绍一种基于云服务的方法
  5. 40岁从零开始学习软件开发,四年后我成了首席研发
  6. redis常用监控命令
  7. 用JavaScript语言制作简易版轮播图
  8. 只出现一次的数字 (桶排序和位运算)
  9. LeetCode112. 路径总和(DFS)(递归)
  10. java中 CopyOnWriteArrayList 的使用
  11. 图片版坦克大战其他相关的 类(三)
  12. 液压减振器 matlab,摩托车液压减振器内泄漏对阻尼力影响计算及其对策
  13. 从零开始设计一款APP之如何做原型图
  14. 普通计算机用的是什么屏幕,电脑显示器什么面板最好?IPS/TN/PLS/VA面板的显示器区别...
  15. 计算机合并单元格怎么操作,excel怎么合并单元格方法
  16. 简单搭建一个属于自己的视频网站
  17. 罗技键盘连计算机,罗技键盘怎么连接电脑
  18. Google Chrome误删书签的恢复方式!
  19. CAN波特率常规波特率索引值对照表及高级模式
  20. 微机原理与接口技术(第6版)第六章习题1、3、10、13

热门文章

  1. java小项目-继承-接口-Swing窗口(一共5个demo)
  2. 苏宁大数据怎么运营_苏宁首个无人店大数据曝光,其消费人群是如何分布的?...
  3. html事件页面切换表格,表格页面切换快捷键 可以使用快捷键CTRL+TAB键
  4. CMake file命令参数GLOB和GLOB_RECURSE
  5. qt toggled trigger clicked区别
  6. matlab 股票分时图_利用Matlab读取股市数据
  7. 51单片机最小系统及晶振电容的选择
  8. 关于word中最后一个分节符导致的空白页删除问题
  9. 虚拟资源项目整合能赚钱?有人靠着虚拟资源整合实操再发布月入万元
  10. linux让别人电脑蓝屏,教你如何让别人电脑瞬间蓝屏!只需要两个键,装逼神器,值得拥有...