Activity启动过程

首语

Activity作为Android四大组件中使用最频繁的组件,也是和用户交互最多的组件,可见它在Android技术体系的核心地位,了解Activity的启动过程可以帮助我们更好的了解Android系统和使用Activity。

文章目录

      • 首语
      • Activity启动过程
        • 根Activity(应用程序)启动过程
        • 普通Activity的启动过程
        • 进程调用
      • 补充
        • 消息循环创建过程
          • 主线程 Looper.loop() 死循环为何不会ANR
          • Looper.loop()死循环为何不会导致CPU占用率过高
      • 总结

Activity启动过程

当一个应用程序启动Activity时,会调用startActivity方法,startActivity方法实现在ContextWrapper中,它继承自Context,调用mBase的startActivity方法,mBase是一个Context对象,它是在attachBaseContext方法中被赋值的,具体类型为ContextImpl,最终实现在ContextImpl类startActivity方法中,后面我们会分析到这部分。

源码路径:frameworks/base/core/java/android/content/ContextWrapper.java

Context mBase;
protected void attachBaseContext(Context base) {if (mBase != null) {throw new IllegalStateException("Base context already set");}mBase = base;
}
@Override
public void startActivity(Intent intent, @Nullable Bundle options) {mBase.startActivity(intent, options);
}

mMainThread类型为ActivityThread,它是当前应用程序进程的主线程。然后调用ActivityThread类的getInstrumentation方法,返回Instrumentation对象。

源码路径:frameworks/base/core/java/android/app/ContextImpl.java

@Overridepublic void startActivity(Intent intent, Bundle options) {warnIfCallingFromSystemProcess();// Calling start activity from outside an activity without FLAG_ACTIVITY_NEW_TASK is// generally not allowed, except if the caller specifies the task id the activity should// be launched in. A bug was existed between N and O-MR1 which allowed this to work. We// maintain this for backwards compatibility.final int targetSdkVersion = getApplicationInfo().targetSdkVersion;if ((intent.getFlags() & Intent.FLAG_ACTIVITY_NEW_TASK) == 0&& (targetSdkVersion < Build.VERSION_CODES.N|| targetSdkVersion >= Build.VERSION_CODES.P)&& (options == null|| ActivityOptions.fromBundle(options).getLaunchTaskId() == -1)) {throw new AndroidRuntimeException("Calling startActivity() from outside of an Activity "+ " context requires the FLAG_ACTIVITY_NEW_TASK flag."+ " Is this really what you want?");}mMainThread.getInstrumentation().execStartActivity(getOuterContext(), mMainThread.getApplicationThread(), null,(Activity) null, intent, -1, options);}

源码路径:frameworks/base/core/java/android/app/ActivityThread.java

public Instrumentation getInstrumentation(){return mInstrumentation;
}

Instrumentation类主要是用来监控应用程序和系统的交互。首先调用ActivityTaskManager类的getService方法获取对应Service的代理对象,接着调用它的startActivity方法。

源码路径:frameworks/base/core/java/android/app/Instrumentation.java

public ActivityResult execStartActivity(Context who, IBinder contextThread, IBinder token, Activity target,Intent intent, int requestCode, Bundle options) {...try {intent.migrateExtraStreamToClipData(who);intent.prepareToLeaveProcess(who);int result = ActivityTaskManager.getService().startActivity(whoThread,who.getOpPackageName(), who.getAttributionTag(), 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;}

getService方法调用IActivityTaskManagerSingleton的get方法,IActivityTaskManagerSingleton是一个Singleton类,通过ServiceManager来获取名为"activity_task"的Service引用,然后将其转换为IActivityTaskManager类型的对象,IActivityTaskManager是AIDL工具编译自动生成的,文件路径为:frameworks/base/core/java/android/app/IActivityTaskManager.aidl。为实现进程通信,名为"activity_task"的Service也需要继承IActivityTaskManager并实现相应的方法,这个Service为ActivityTaskManagerService。调用ActivityTaskManagerService的startActivity方法。

源码路径:frameworks/base/core/java/android/app/ActivityTaskManager.java

public static IActivityTaskManager getService() {return IActivityTaskManagerSingleton.get();
}
private static final Singleton<IActivityTaskManager> IActivityTaskManagerSingleton =new Singleton<IActivityTaskManager>() {@Overrideprotected IActivityTaskManager create() {//activity_taskfinal IBinder b = ServiceManager.getService(Context.ACTIVITY_TASK_SERVICE);return IActivityTaskManager.Stub.asInterface(b);}};

startActivity方法调用startActivityAsUser方法,调用getActivityStartController方法获取ActivityStartController实例执行obtainStarter方法,它返回ActivityStarter实例,ActivityStarter是启动Activity的控制类。然后传递Activity的信息,执行execute方法。

源码路径:frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java

	@Overridepublic final int startActivity(IApplicationThread caller, String callingPackage,String callingFeatureId, Intent intent, String resolvedType, IBinder resultTo,String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo,Bundle bOptions) {return startActivityAsUser(caller, callingPackage, callingFeatureId, intent, resolvedType,resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions,UserHandle.getCallingUserId());}@Overridepublic int startActivityAsUser(IApplicationThread caller, String callingPackage,String callingFeatureId, Intent intent, String resolvedType, IBinder resultTo,String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo,Bundle bOptions, int userId) {return startActivityAsUser(caller, callingPackage, callingFeatureId, intent, resolvedType,resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,true /*validateIncomingUser*/);}
private int startActivityAsUser(IApplicationThread caller, String callingPackage,@Nullable String callingFeatureId, Intent intent, String resolvedType,IBinder resultTo, String resultWho, int requestCode, int startFlags,ProfilerInfo profilerInfo, Bundle bOptions, int userId, boolean validateIncomingUser) {...// TODO: Switch to user app stacks here.return getActivityStartController().obtainStarter(intent, "startActivityAsUser")//传递Activity信息.setCaller(caller).setCallingPackage(callingPackage).setCallingFeatureId(callingFeatureId).setResolvedType(resolvedType).setResultTo(resultTo).setResultWho(resultWho).setRequestCode(requestCode).setStartFlags(startFlags).setProfilerInfo(profilerInfo).setActivityOptions(bOptions).setUserId(userId).execute();}
ActivityStartController getActivityStartController() {return mActivityStartController;}

源码路径:frameworks/base/services/core/java/com/android/server/wm/ActivityStartController.java

    ActivityStarter obtainStarter(Intent intent, String reason) {return mFactory.obtain().setIntent(intent).setReason(reason);}

execute方法会执行startActivityInner方法,startActivityInner方法中做了task相关的计算,以及任务栈是否存在,不存在重新创建,最终调用到RootWindowContainer类的resumeFocusedTasksTopActivities方法中,根据栈顶Activity状态进行不同处理。getFocusedRootTask获取聚焦可见的任务栈,focusedRoot为Task类型,会执行resumeTopActivityUncheckedLocked方法。

源码路径:frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java

int execute() {try {...res = executeRequest(mRequest);}
}
private int executeRequest(Request request) {...if (resultTo != null) {//ActivityRecord为Activity的描述类,记录Activity所有信息sourceRecord = ActivityRecord.isInAnyTask(resultTo);}mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,request.voiceInteractor, startFlags, true /* doResume */, checkedOptions,inTask, inTaskFragment, restrictedBgActivity, intentGrants);
}
private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,int startFlags, boolean doResume, ActivityOptions options, Task inTask,TaskFragment inTaskFragment, boolean restrictedBgActivity,NeededUriGrants intentGrants) {...result = startActivityInner(r, sourceRecord, voiceSession, voiceInteractor,startFlags, doResume, options, inTask, inTaskFragment, restrictedBgActivity,intentGrants);
}
int startActivityInner(final ActivityRecord r, ActivityRecord sourceRecord,IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,int startFlags, boolean doResume, ActivityOptions options, Task inTask,TaskFragment inTaskFragment, boolean restrictedBgActivity,NeededUriGrants intentGrants) {//初始化Activity的statesetInitialState(r, options, inTask, inTaskFragment, doResume, startFlags, sourceRecord,voiceSession, voiceInteractor, restrictedBgActivity);//计算启动task的flagcomputeLaunchingTaskFlags();//计算root taskcomputeSourceRootTask();   //不存在任务栈重新创建if (mTargetRootTask == null) {mTargetRootTask = getOrCreateRootTask(mStartActivity, mLaunchFlags, targetTask,mOptions);}if (newTask) {final Task taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null)? mSourceRecord.getTask() : null;setNewTask(taskToAffiliate);} else if (mAddingToTask) {addOrReparentStartingActivity(targetTask, "adding to task");}...mRootWindowContainer.resumeFocusedTasksTopActivities(mTargetRootTask, mStartActivity, mOptions, 			mTransientLaunch);        
}

源码路径:frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java

boolean resumeFocusedTasksTopActivities() {return resumeFocusedTasksTopActivities(null, null, null);}boolean resumeFocusedTasksTopActivities(Task targetRootTask, ActivityRecord target, ActivityOptions targetOptions) {return resumeFocusedTasksTopActivities(targetRootTask, target, targetOptions,false /* deferPause */);}boolean resumeFocusedTasksTopActivities(Task targetRootTask, ActivityRecord target, ActivityOptions targetOptions,boolean deferPause) {...display.forAllRootTasks(rootTask -> {//根据栈顶Activity状态进程不同处理final ActivityRecord topRunningActivity = rootTask.topRunningActivity();//RESUMED状态if (rootTask.getDisplayArea().isTopRootTask(rootTask)&& topRunningActivity.isState(RESUMED)) {// Kick off any lingering app transitions form the MoveTaskToFront// operation, but only consider the top task and root-task on that// display.rootTask.executeAppTransition(targetOptions);} else {resumedOnDisplay[0] |= topRunningActivity.makeActiveIfNeeded(target);}}final Task focusedRoot = display.getFocusedRootTask();                                if (focusedRoot != null) {result |= focusedRoot.resumeTopActivityUncheckedLocked(target, targetOptions);} else if (targetRootTask == null) {result |= resumeHomeActivity(null /* prev */, "no-focusable-task",display.getDefaultTaskDisplayArea());}}

resumeTopActivityUncheckedLocked方法会调用resumeTopActivityInnerLocked方法,获取TaskFragment实例,调用resumeTopActivity方法。mTaskSupervisor类型为ActivityTaskSupervisor,最终调用startSpecificActivity方法。

源码路径:frameworks/base/services/core/java/com/android/server/wm/Task.java

boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {return resumeTopActivityUncheckedLocked(prev, options, false /* skipPause */);}@GuardedBy("mService")private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options,boolean deferPause) {if (!mAtmService.isBooting() && !mAtmService.isBooted()) {// Not ready yet!return false;}final ActivityRecord topActivity = topRunningActivity(true /* focusableOnly */);if (topActivity == null) {// There are no activities left in this task, let's look somewhere else.return resumeNextFocusableActivityWhenRootTaskIsEmpty(prev, options);}final boolean[] resumed = new boolean[1];final TaskFragment topFragment = topActivity.getTaskFragment();resumed[0] = topFragment.resumeTopActivity(prev, options, deferPause);forAllLeafTaskFragments(f -> {if (topFragment == f) {return;}if (!f.canBeResumed(null /* starting */)) {return;}resumed[0] |= f.resumeTopActivity(prev, options, deferPause);}, true);return resumed[0];}

源码路径:frameworks/base/services/core/java/com/android/server/wm/TaskFragment.java

final boolean resumeTopActivity(ActivityRecord prev, ActivityOptions options,boolean deferPause) {...mTaskSupervisor.startSpecificActivity(next, true, true);
}

startSpecificActivity中就比较关键了,因为做了进程的判断,如果Activity有对应进程,并且启动。它就会调用realStartActivityLocked方法启动一个普通Activity,如果Activity还没有对应进程或进程没启动,则需要创建或启动Activity对应的应用程序进程,因为Activity必须运行在应用程序进程中,mService实例为ActivityTaskManagerService,调用startProcessAsync方法创建或启动应用程序进程。

源码路径:frameworks/base/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java

void startSpecificActivity(ActivityRecord r, boolean andResume, boolean checkConfig) {// Is this activity's application already running?//获取Activity所在的应用程序进程final WindowProcessController wpc =mService.getProcessController(r.processName, r.info.applicationInfo.uid);boolean knownToBeDead = false;//Activity存在进程并且已经启动if (wpc != null && wpc.hasThread()) {try {//启动ActivityrealStartActivityLocked(r, wpc, 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.knownToBeDead = true;// Remove the process record so it won't be considered as alive.mService.mProcessNames.remove(wpc.mName, wpc.mUid);mService.mProcessMap.remove(wpc.getPid());}r.notifyUnknownVisibilityLaunchedForKeyguardTransition();final boolean isTop = andResume && r.isTopRunningActivity();//创建或启动应用程序进程mService.startProcessAsync(r, knownToBeDead, isTop,isTop ? HostingRecord.HOSTING_TYPE_TOP_ACTIVITY: HostingRecord.HOSTING_TYPE_ACTIVITY);}
根Activity(应用程序)启动过程

Launcher启动过程文章中,我们分析了Launcher通过Context类的startActivity方法来启动根Activity。也就是启动应用程序。流程和上述一致,最终来到ActivityTaskManagerService类的startProcessAsync方法进行创建或启动应用程序进程。

startProcessAsync方法中发送了一条消息,通过PooledLambda类的obtainMessage方法创建一条消息并设置线程,Handler处理消息时会运行这个线程,进而执行PooledLambdaImpl类的invoke方法,最终调用OctConsumer的accept方法,accept方法中调用了ActivityManagerInternal类的startProcess方法,传入的ActivityManagerInternal为mAmInternal,而mAmInternal是在onActivityManagerInternalAdded方法中进行赋值的,那是谁调用了这个方法呢?

public void onActivityManagerInternalAdded() {synchronized (mGlobalLock) {mAmInternal = LocalServices.getService(ActivityManagerInternal.class);mUgmInternal = LocalServices.getService(UriGrantsManagerInternal.class);}
}
void startProcessAsync(ActivityRecord activity, boolean knownToBeDead, boolean isTop,String hostingType) {try {if (Trace.isTagEnabled(TRACE_TAG_WINDOW_MANAGER)) {Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "dispatchingStartProcess:"+ activity.processName);}// Post message to start process to avoid possible deadlock of calling into AMS with the// ATMS lock held.final Message m = PooledLambda.obtainMessage(ActivityManagerInternal::startProcess,mAmInternal, activity.processName, activity.info.applicationInfo, knownToBeDead,isTop, hostingType, activity.intent.getComponent());mH.sendMessage(m);} finally {Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);}}

源码路径:frameworks/base/core/java/com/android/internal/util/function/pooled/PooledLambda.java

import static com.android.internal.util.function.pooled.PooledLambdaImpl.acquire;
static <A, B, C, D, E, F, G, H> Message obtainMessage(OctConsumer<? super A, ? super B, ? super C, ? super D, ? super E, ? super F, ? super G,? super H> function, A arg1, B arg2, C arg3, D arg4, E arg5, F arg6, G arg7,H arg8) {synchronized (Message.sPoolSync) {//PooledLambdaImpl类的acquire方法获取PooledRunnablePooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool,function, 8, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8,null, null, null, null);//设置Message的Runnablereturn Message.obtain().setCallback(callback.recycleOnUse());}}
public interface OctConsumer<A, B, C, D, E, F, G, H> {void accept(A a, B b, C c, D d, E e, F f, G g, H h);
}

源码路径:frameworks/base/core/java/com/android/internal/util/function/pooled/PooledLambdaImpl.java

@OverrideR invoke(Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7,Object a8, Object a9, Object a10, Object a11) {...return doInvoke();}
private R doInvoke() {switch (argCount) {case 8: {switch (returnType) {case LambdaType.ReturnType.VOID: {((OctConsumer) mFunc).accept(popArg(0), popArg(1),popArg(2), popArg(3), popArg(4),popArg(5), popArg(6), popArg(7));return null;...}
}

SystemServer进程启动过程文章中,我们知道ActivityTaskManagerService是在SystemServer类的startBootstrapServices方法中启动的,接着又启动了AMS,通过调用ActivityManagerService类的onStart方法。在start方法可以看到mInternal被添加到LocalServices中,然后将mInternal通过ActivityTaskManagerService的onActivityManagerInternalAdded方法传递给ActivityTaskManagerService,

那看下mInternal对startProcess方法的实现,在ActivityManagerService类创建了一个LocalService内部类,实现了startProcess方法。

startProcess方法中调用startProcessLocked方法,接着调用ProcessList类的startProcessLocked方法,ProcessList类是AMS用来管理进程的。

源码路径:frameworks/bae/services/core/java/com/android/server/am/ActivityManagerService.java

@Override
public void onStart() {mService.start();
}
private void start() {//LocalServices添加mInternalLocalServices.addService(ActivityManagerInternal.class, mInternal);LocalManagerRegistry.addManager(ActivityManagerLocal.class,(ActivityManagerLocal) mInternal);//ActivityTaskManagerService的onActivityManagerInternalAdded方法传递mInternalmActivityTaskManager.onActivityManagerInternalAdded();mPendingIntentController.onActivityManagerInternalAdded();mAppProfiler.onActivityManagerInternalAdded();CriticalEventLog.init();
}
public ActivityManagerService(Context systemContext, ActivityTaskManagerService atm) {...mInternal = new LocalService();    
}
public final class LocalService extends ActivityManagerInternalimplements ActivityManagerLocal {@Overridepublic void startProcess(String processName, ApplicationInfo info, boolean knownToBeDead,boolean isTop, String hostingType, ComponentName hostingName) {try {synchronized (ActivityManagerService.this) {startProcessLocked(processName, info, knownToBeDead, 0 /* intentFlags */,new HostingRecord(hostingType, hostingName, isTop),ZYGOTE_POLICY_FLAG_LATENCY_SENSITIVE, false /* allowWhileBooting */,false /* isolated */);}} finally {Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);}}
}
final ProcessList mProcessList;
final ProcessRecord startProcessLocked(String processName,ApplicationInfo info, boolean knownToBeDead, int intentFlags,HostingRecord hostingRecord, int zygotePolicyFlags, boolean allowWhileBooting,boolean isolated) {return mProcessList.startProcessLocked(processName, info, knownToBeDead, intentFlags,hostingRecord, zygotePolicyFlags, allowWhileBooting, isolated, 0 /* isolatedUid */,false /* isSdkSandbox */, 0 /* sdkSandboxClientAppUid */,null /* sdkSandboxClientAppPackage */,null /* ABI override */, null /* entryPoint */,null /* entryPointArgs */, null /* crashHandler */);}

ProcessList类中对startProcessLocked进行重载,做了大量进程创建前的准备工作,最终调用startProcess方法,对hostingRecord的hostingZygote进行判断,hostingRecord是从ActivityManagerService类的startProcess方法中传递过来的,创建了一个HostingRecord,通过其构造函数可知hostingZygote为REGULAR_ZYGOTE,因此调用Process.start方法去创建应用程序进程。传递进程名(默认为包名),用户id,用户组id等。Process的start方法中调用了ZygoteProcess的start方法。

源码路径:frameworks/base/services/core/java/com/android/server/am/ProcessList.java

ProcessRecord startProcessLocked(String processName, ApplicationInfo info,boolean knownToBeDead, int intentFlags, HostingRecord hostingRecord,int zygotePolicyFlags, boolean allowWhileBooting, boolean isolated, int isolatedUid,boolean isSdkSandbox, int sdkSandboxUid, String sdkSandboxClientAppPackage,String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {...final boolean success =startProcessLocked(app, hostingRecord, zygotePolicyFlags, abiOverride);
}
boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,int zygotePolicyFlags, String abiOverride) {return startProcessLocked(app, hostingRecord, zygotePolicyFlags,false /* disableHiddenApiChecks */, false /* disableTestApiChecks */,abiOverride);}
boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,int zygotePolicyFlags, boolean disableHiddenApiChecks, boolean disableTestApiChecks,String abiOverride) {...//获取应用程序进程的用户idint uid = app.uid;//用户组id进行赋值    app.setGids(gids);    //应用程序进程的主线程类名final String entryPoint = "android.app.ActivityThread";return startProcessLocked(hostingRecord, entryPoint, app, uid, gids,runtimeFlags, zygotePolicyFlags, mountExternal, seInfo, requiredAbi,instructionSet, invokeWith, startUptime, startElapsedTime);
}
boolean startProcessLocked(HostingRecord hostingRecord, String entryPoint, ProcessRecord app,int uid, int[] gids, int runtimeFlags, int zygotePolicyFlags, int mountExternal,String seInfo, String requiredAbi, String instructionSet, String invokeWith,long startUptime, long startElapsedTime) {final Process.ProcessStartResult startResult = startProcess(hostingRecord,entryPoint, app,uid, gids, runtimeFlags, zygotePolicyFlags, mountExternal, seInfo,requiredAbi, instructionSet, invokeWith, startUptime);handleProcessStartedLocked(app, startResult.pid, startResult.usingWrapper,startSeq, false);
}
private Process.ProcessStartResult startProcess(HostingRecord hostingRecord, String entryPoint,ProcessRecord app, int uid, int[] gids, int runtimeFlags, int zygotePolicyFlags,int mountExternal, String seInfo, String requiredAbi, String instructionSet,String invokeWith, long startTime) {...if (hostingRecord.usesWebviewZygote()) {startResult = startWebView(entryPoint,app.processName, uid, uid, gids, runtimeFlags, mountExternal,app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,app.info.dataDir, null, app.info.packageName,app.getDisabledCompatChanges(),new String[]{PROC_START_SEQ_IDENT + app.getStartSeq()});} else if (hostingRecord.usesAppZygote()) {final AppZygote appZygote = createAppZygoteForProcessIfNeeded(app);// We can't isolate app data and storage data as parent zygote already did that.startResult = appZygote.getProcess().start(entryPoint,app.processName, uid, uid, gids, runtimeFlags, mountExternal,app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,app.info.dataDir, null, app.info.packageName,/*zygotePolicyFlags=*/ ZYGOTE_POLICY_FLAG_EMPTY, isTopApp,app.getDisabledCompatChanges(), pkgDataInfoMap, allowlistedAppDataInfoMap,false, false,new String[]{PROC_START_SEQ_IDENT + app.getStartSeq()});} else {regularZygote = true;startResult = Process.start(entryPoint,app.processName, uid, uid, gids, runtimeFlags, mountExternal,app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,app.info.dataDir, invokeWith, app.info.packageName, zygotePolicyFlags,isTopApp, app.getDisabledCompatChanges(), pkgDataInfoMap,allowlistedAppDataInfoMap, bindMountAppsData, bindMountAppStorageDirs,new String[]{PROC_START_SEQ_IDENT + app.getStartSeq()});}
}

源码路径:frameworks/base/core/java/android/os/Process.java

public static final ZygoteProcess ZYGOTE_PROCESS = new ZygoteProcess();public static ProcessStartResult start(@NonNull final String processClass,@Nullable final String niceName,int uid, int gid, @Nullable int[] gids,int runtimeFlags,int mountExternal,int targetSdkVersion,@Nullable String seInfo,@NonNull String abi,@Nullable String instructionSet,@Nullable String appDataDir,@Nullable String invokeWith,@Nullable String packageName,int zygotePolicyFlags,boolean isTopApp,@Nullable long[] disabledCompatChanges,@Nullable Map<String, Pair<String, Long>>pkgDataInfoMap,@Nullable Map<String, Pair<String, Long>>whitelistedDataInfoMap,boolean bindMountAppsData,boolean bindMountAppStorageDirs,@Nullable String[] zygoteArgs) {return ZYGOTE_PROCESS.start(processClass, niceName, uid, gid, gids,runtimeFlags, mountExternal, targetSdkVersion, seInfo,abi, instructionSet, appDataDir, invokeWith, packageName,zygotePolicyFlags, isTopApp, disabledCompatChanges,pkgDataInfoMap, whitelistedDataInfoMap, bindMountAppsData,bindMountAppStorageDirs, zygoteArgs);
}

start方法调用startViaZygote方法,startViaZygote方法保存进程参数,然后调用zygoteSendArgsAndGetResult方法,第一个参数为ZygoteState,由openZygoteSocketIfNeeded方法获取,ZygoteState是ZygoteProcess的内部类,表示与Zygote进程通信的状态,zygoteSendArgsAndGetResult调用attemptZygoteSendArgsAndGetResult方法,将参数写入到ZygoteState中。

Zygote 进程启动过程文章中,我们知道Zygote启动过程中会调用ZygoteServer创建两个server端的socket,然后启动SystemServer进程,最后等待AMS来创建新的应用程序进程。openZygoteSocketIfNeeded方法中,会与Zygote进程建立socket连接,在Zygote 进程启动过程文章中,Zygote启动脚本有多种,根据不同的启动模式建立不同的连接。连接成功后,Zygote进程就会收到创建新的应用程序进程的请求。在Zygote 进程启动过程文章中,有一个startClass,最后反射获取它的main方法,它就是之前我们提到的android.app.ActivityThread,调用了mMethod的invoke方法,ActivityThread类的main方法会被动态调用。应用程序进程创建完成后,进入了Activity Thread的main方法中。

源码路径:frameworks/base/core/java/android/os/ZygoteProcess.java

public final Process.ProcessStartResult start(@NonNull final String processClass,final String niceName,int uid, int gid, @Nullable int[] gids,int runtimeFlags, int mountExternal,int targetSdkVersion,@Nullable String seInfo,@NonNull String abi,@Nullable String instructionSet,@Nullable String appDataDir,@Nullable String invokeWith,@Nullable String packageName,int zygotePolicyFlags,boolean isTopApp,@Nullable long[] disabledCompatChanges,@Nullable Map<String, Pair<String, Long>>pkgDataInfoMap,@Nullable Map<String, Pair<String, Long>>allowlistedDataInfoList,boolean bindMountAppsData,boolean bindMountAppStorageDirs,@Nullable String[] zygoteArgs) {try {return startViaZygote(processClass, niceName, uid, gid, gids,runtimeFlags, mountExternal, targetSdkVersion, seInfo,abi, instructionSet, appDataDir, invokeWith, /*startChildZygote=*/ false,packageName, zygotePolicyFlags, isTopApp, disabledCompatChanges,pkgDataInfoMap, allowlistedDataInfoList, bindMountAppsData,bindMountAppStorageDirs, zygoteArgs);...
}
private Process.ProcessStartResult startViaZygote(@NonNull final String processClass,@Nullable final String niceName,final int uid, final int gid,@Nullable final int[] gids,int runtimeFlags, int mountExternal,int targetSdkVersion,@Nullable String seInfo,@NonNull String abi,@Nullable String instructionSet,@Nullable String appDataDir,@Nullable String invokeWith,boolean startChildZygote,@Nullable String packageName,int zygotePolicyFlags,boolean isTopApp,@Nullable long[] disabledCompatChanges,@Nullable Map<String, Pair<String, Long>>pkgDataInfoMap,@Nullable Map<String, Pair<String, Long>>allowlistedDataInfoList,boolean bindMountAppsData,boolean bindMountAppStorageDirs,@Nullable String[] extraArgs)throws ZygoteStartFailedEx {//添加进程参数ArrayList<String> argsForZygote = new ArrayList<>();argsForZygote.add("--runtime-args");argsForZygote.add("--setuid=" + uid);argsForZygote.add("--setgid=" + gid);argsForZygote.add("--runtime-flags=" + runtimeFlags);if (mountExternal == Zygote.MOUNT_EXTERNAL_DEFAULT) {argsForZygote.add("--mount-external-default");} else if (mountExternal == Zygote.MOUNT_EXTERNAL_INSTALLER) {argsForZygote.add("--mount-external-installer");} else if (mountExternal == Zygote.MOUNT_EXTERNAL_PASS_THROUGH) {argsForZygote.add("--mount-external-pass-through");} else if (mountExternal == Zygote.MOUNT_EXTERNAL_ANDROID_WRITABLE) {argsForZygote.add("--mount-external-android-writable");}argsForZygote.add("--target-sdk-version=" + targetSdkVersion);// --setgroups is a comma-separated listif (gids != null && gids.length > 0) {final StringBuilder sb = new StringBuilder();sb.append("--setgroups=");final int sz = gids.length;for (int i = 0; i < sz; i++) {if (i != 0) {sb.append(',');}sb.append(gids[i]);}argsForZygote.add(sb.toString());argsForZygote.add(processClass);...return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi),zygotePolicyFlags,argsForZygote);}
}
private Process.ProcessStartResult zygoteSendArgsAndGetResult(ZygoteState zygoteState, int zygotePolicyFlags, @NonNull ArrayList<String> args)throws ZygoteStartFailedEx {return attemptZygoteSendArgsAndGetResult(zygoteState, msgStr);
}
private Process.ProcessStartResult attemptZygoteSendArgsAndGetResult(ZygoteState zygoteState, String msgStr) throws ZygoteStartFailedEx {try {final BufferedWriter zygoteWriter = zygoteState.mZygoteOutputWriter;final DataInputStream zygoteInputStream = zygoteState.mZygoteInputStream;//参数写入ZygoteStatezygoteWriter.write(msgStr);zygoteWriter.flush();Process.ProcessStartResult result = new Process.ProcessStartResult();result.pid = zygoteInputStream.readInt();result.usingWrapper = zygoteInputStream.readBoolean();if (result.pid < 0) {throw new ZygoteStartFailedEx("fork() failed");}return result;} catch (IOException ex) {zygoteState.close();Log.e(LOG_TAG, "IO Exception while communicating with Zygote - "+ ex.toString());throw new ZygoteStartFailedEx(ex);}
}
private ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx {try {//与Zygote进程建立socket连接attemptConnectionToPrimaryZygote();//连接Zygote主模式返回的Zygote是否和应用程序进程所需要的ABI匹配if (primaryZygoteState.matches(abi)) {return primaryZygoteState;}//不匹配,连接Zygote辅模式if (mZygoteSecondarySocketAddress != null) {// The primary zygote didn't match. Try the secondary.attemptConnectionToSecondaryZygote();//连接Zygote辅模式返回的Zygote是否和应用程序进程所需要的ABI匹配	if (secondaryZygoteState.matches(abi)) {return secondaryZygoteState;}}} catch (IOException ioe) {throw new ZygoteStartFailedEx("Error connecting to zygote", ioe);}throw new ZygoteStartFailedEx("Unsupported zygote ABI: " + abi);
}  
private void attemptConnectionToPrimaryZygote() throws IOException {if (primaryZygoteState == null || primaryZygoteState.isClosed()) {primaryZygoteState =ZygoteState.connect(mZygoteSocketAddress, mUsapPoolSocketAddress);maybeSetApiDenylistExemptions(primaryZygoteState, false);maybeSetHiddenApiAccessLogSampleRate(primaryZygoteState);}
}
private void attemptConnectionToSecondaryZygote() throws IOException {if (secondaryZygoteState == null || secondaryZygoteState.isClosed()) {secondaryZygoteState =ZygoteState.connect(mZygoteSecondarySocketAddress,mUsapPoolSecondarySocketAddress);maybeSetApiDenylistExemptions(secondaryZygoteState, false);maybeSetHiddenApiAccessLogSampleRate(secondaryZygoteState);}
}

ActivityThread的main方法中,创建了一个ActivityThread实例,调用attach方法,进程通信调用ActivityManagerService的attachApplication方法。

源码路径:frameworks\base\core\java\android\app\ActivityThread.java

public static void main(String[] args) {...ActivityThread thread = new ActivityThread();thread.attach(false, startSeq);
}
private void attach(boolean system, long startSeq) {if (!system) {android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",UserHandle.myUserId());RuntimeInit.setApplicationObject(mAppThread.asBinder());final IActivityManager mgr = ActivityManager.getService();try {mgr.attachApplication(mAppThread, startSeq);...}

attachApplication方法调用attachApplicationLocked方法,mAtmInternal为ActivityTaskManagerInternal类型,调用attachApplication方法。

源码路径:frameworks\base\services\core\java\com\android\server\am\ActivityManagerService.java

public ActivityTaskManagerInternal mAtmInternal;
public ActivityManagerService(Context systemContext, ActivityTaskManagerService atm) {mAtmInternal = LocalServices.getService(ActivityTaskManagerInternal.class);
}
@Overridepublic final void attachApplication(IApplicationThread thread, long startSeq) {if (thread == null) {throw new SecurityException("Invalid application interface");}synchronized (this) {int callingPid = Binder.getCallingPid();final int callingUid = Binder.getCallingUid();final long origId = Binder.clearCallingIdentity();attachApplicationLocked(thread, callingPid, callingUid, startSeq);Binder.restoreCallingIdentity(origId);}
}
private boolean attachApplicationLocked(@NonNull IApplicationThread thread,int pid, int callingUid, long startSeq) {...//创建Applicationthread.bindApplication(processName, appInfo,app.sdkSandboxClientAppVolumeUuid, app.sdkSandboxClientAppPackage,providerList, null, profilerInfo, null, null, null, testMode,mBinderTransactionTrackingEnabled, enableTrackAllocation,isRestrictedBackupMode || !normalMode, app.isPersistent(),new Configuration(app.getWindowProcessController().getConfiguration()),app.getCompat(), getCommonServicesLocked(app.isolated),mCoreSettingsObserver.getCoreSettingsLocked(),buildSerial, autofillOptions, contentCaptureOptions,app.getDisabledCompatChanges(), serializedSystemFontMap,app.getStartElapsedTime(), app.getStartUptime());if (normalMode) {try {didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());} catch (Exception e) {Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);badApp = true;}}
}

SystemServer进程启动ActivityTaskManagerService时候会将ActivityTaskManagerInternal添加到LocalServices中,因此,attachApplication方法实现在ActivityTaskManagerService类的LocalService中,调用RootWindowContainer类的attachApplication方法。

源码路径:frameworks\base\services\core\java\com\android\server\wm\ActivityTaskManagerService.java

RootWindowContainer mRootWindowContainer;@Override
public void onStart() {publishBinderService(Context.ACTIVITY_TASK_SERVICE, mService);mService.start();
}
private void start() {LocalServices.addService(ActivityTaskManagerInternal.class, mInternal);
}
public ActivityTaskManagerService(Context context) {...mInternal = new LocalService();
}final class LocalService extends ActivityTaskManagerInternal {@Overridepublic boolean attachApplication(WindowProcessController wpc) throws RemoteException {synchronized (mGlobalLockWithoutBoost) {if (Trace.isTagEnabled(TRACE_TAG_WINDOW_MANAGER)) {Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "attachApplication:" + wpc.mName);}try {return mRootWindowContainer.attachApplication(wpc);} finally {Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);}}} }

forAllRootTasks方法来自WindowContainer类中。

源码路径:frameworks\base\services\core\java\com\android\server\wm\RootWindowContainer.java

class RootWindowContainer extends WindowContainer<DisplayContent>implements DisplayManager.DisplayListener {private final AttachApplicationHelper mAttachApplicationHelper = new AttachApplicationHelper();ActivityTaskSupervisor mTaskSupervisor;
boolean attachApplication(WindowProcessController app) throws RemoteException {try {return mAttachApplicationHelper.process(app);} finally {mAttachApplicationHelper.reset();}}
private class AttachApplicationHelper implements Consumer<Task>, Predicate<ActivityRecord> {boolean process(WindowProcessController app) throws RemoteException {mApp = app;for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {//来自WindowContainer类getChildAt(displayNdx).forAllRootTasks(this);if (mRemoteException != null) {throw mRemoteException;}}if (!mHasActivityStarted) {ensureActivitiesVisible(null /* starting */, 0 /* configChanges */,false /* preserveWindows */);}return mHasActivityStarted;}}@Overridepublic void accept(Task rootTask) {mTop = rootTask.topRunningActivity();rootTask.forAllActivities(this);}@Overridepublic boolean test(ActivityRecord r) {...try {if (mTaskSupervisor.realStartActivityLocked(r, mApp,mTop == r && r.getTask().canBeResumed(r) /* andResume */,true /* checkConfig */)) {mHasActivityStarted = true;}...return false;}}
}

WindowContainer类是一个窗口容器类,它定义了能够直接或者间接以层级结构的形式持有窗口的类的通用功能,它也是WMS(WindowManagerService)的重要基类。mChildren中保存当前WindowContainer持有的所有子容器,列表的顺序也就是子容器出现在屏幕上的顺序,最顶层的子容器位于队尾。

在WMS体系中,一个WindowState对象就代表了一个窗口,持有WindowState类的对象有很多,其中包含ActivityRecord,在WMS中一个ActivityRecord对象就代表一个Activity对象,存放ActivityRecord的是Task类,而存放Task的是TaskDisplayArea类,Task类继承于TaskFragment,因为mChildren中也存在Task,这时forAllRootTasks方法中遍历会调用到Task重写的forAllRootTasks方法,即AttachApplicationHelper类的accept方法。accpet方法中会调用task的forAllActivities方法,因为mChildren中也存在ActivityRecord,这时会调用ActivityRecord重写的forAllActivities方法。即AttachApplicationHelper类的test方法,test方法中会调用到ActivityTaskSupervisor类的realStartActivityLocked方法。

注意:这里涉及到了WMS的基础知识,后续会从代码角度分析WMS,这里了解即可。

源码路径:frameworks/base/services/core/java/com/android/server/wm/WindowContainer.java

class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<E>implements Comparable<WindowContainer>, Animatable, SurfaceFreezer.Freezable,InsetsControlTarget {protected final WindowList<E> mChildren = new WindowList<E>();void forAllRootTasks(Consumer<Task> callback) {forAllRootTasks(callback, true /* traverseTopToBottom */);}void forAllRootTasks(Consumer<Task> callback, boolean traverseTopToBottom) {int count = mChildren.size();if (traverseTopToBottom) {for (int i = count - 1; i >= 0; --i) {mChildren.get(i).forAllRootTasks(callback, traverseTopToBottom);}} else {for (int i = 0; i < count; i++) {mChildren.get(i).forAllRootTasks(callback, traverseTopToBottom);int newCount = mChildren.size();i -= count - newCount;count = newCount;}}}boolean forAllActivities(Predicate<ActivityRecord> callback) {return forAllActivities(callback, true /*traverseTopToBottom*/);}boolean forAllActivities(Predicate<ActivityRecord> callback, boolean traverseTopToBottom) {if (traverseTopToBottom) {for (int i = mChildren.size() - 1; i >= 0; --i) {if (mChildren.get(i).forAllActivities(callback, traverseTopToBottom)) return true;}} else {final int count = mChildren.size();for (int i = 0; i < count; i++) {if (mChildren.get(i).forAllActivities(callback, traverseTopToBottom)) return true;}}return false;}
}

源码路径:frameworks/base/services/core/java/com/android/server/wm/Task.java

class Task extends TaskFragment {@Overridevoid forAllRootTasks(Consumer<Task> callback, boolean traverseTopToBottom) {if (isRootTask()) {callback.accept(this);}}
}
//frameworks/base/services/core/java/com/android/server/wm/TaskFragment.java
void addChild(ActivityRecord r) {addChild(r, POSITION_TOP);}

源码路径:frameworks/base/services/core/java/com/android/server/wm/ActivityRecord.java

	@Overrideboolean forAllActivities(Predicate<ActivityRecord> callback, boolean traverseTopToBottom) {return callback.test(this);}

到这里,就和前面启动普通Activity的方法realStartActivityLocked接轨了,和普通Activity的启动过程一致。

普通Activity的启动过程

realStartActivityLocked方法中,首先创建ClientTransaction,然后创建LaunchActivityItem,添加到ClientTransaction回调中,LaunchActivityItem继承于ClientTransactionItem,然后调用ActivityTaskManagerService类的getLifecycleManager方法,返回ClientLifecycleManager实例再调用scheduleTransaction方法,执行创建的clientTransaction。

boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,boolean andResume, boolean checkConfig) throws RemoteException {...// Create activity launch transaction.final ClientTransaction clientTransaction = ClientTransaction.obtain(proc.getThread(), r.token);final boolean isTransitionForward = r.isTransitionForward();final IBinder fragmentToken = r.getTaskFragment().getFragmentToken();//创建LaunchActivityItemclientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),System.identityHashCode(r), r.info,// TODO: Have this take the merged configuration instead of separate global// and override configs.mergedConfiguration.getGlobalConfiguration(),mergedConfiguration.getOverrideConfiguration(), r.compat,r.getFilteredReferrer(r.launchedFromPackage), task.voiceInteractor,proc.getReportedProcState(), r.getSavedState(), r.getPersistentSavedState(),results, newIntents, r.takeOptions(), isTransitionForward,proc.createProfilerInfoIfNeeded(), r.assistToken, activityClientController,r.shareableActivityToken, r.getLaunchedFromBubble(), fragmentToken));// Set desired final state.final ActivityLifecycleItem lifecycleItem;if (andResume) {lifecycleItem = ResumeActivityItem.obtain(isTransitionForward);} else {lifecycleItem = PauseActivityItem.obtain();}clientTransaction.setLifecycleStateRequest(lifecycleItem);// 执行transtion.mService.getLifecycleManager().scheduleTransaction(clientTransaction);...
}
ClientLifecycleManager getLifecycleManager() {return mLifecycleManager;}

scheduleTransaction方法又调用了ClientTransaction的schedule方法。

源码路径:frameworks/base/services/core/java/com/android/server/wm/ClientLifecycleManager.java

void scheduleTransaction(ClientTransaction transaction) throws RemoteException {final IApplicationThread client = transaction.getClient();transaction.schedule();if (!(client instanceof Binder)) {transaction.recycle();}}

mClient类型为IApplicationThread,它是在创建clientTransaction时传入的,和前面提到的一样,它是AIDL工具编译自动生成的,文件路径为:frameworks/base/core/java/android/app/IApplicationThread.aidl,为了进程间通信对应的ApplicationThread需要继承它并实现相应的方法。ApplicationThread是Activity Thread的内部类。

源码路径:frameworks/base/core/java/android/app/servertransaction/ClientTransaction.java

private IApplicationThread mClient;
public static ClientTransaction obtain(IApplicationThread client, IBinder activityToken) {ClientTransaction instance = ObjectPool.obtain(ClientTransaction.class);if (instance == null) {instance = new ClientTransaction();}instance.mClient = client;instance.mActivityToken = activityToken;return instance;}
public void schedule() throws RemoteException {mClient.scheduleTransaction(this);}

调用ActivityThread类的scheduleTransaction方法,实现在父类ClientTransactionHandler中。发送了一条消息,Handler实现在ActivityThread类中,mTransactionExecutor类型为TransactionExecutor,调用其execute方法。

源码路径:frameworks/base/core/java/android/app/ActivityThread.java

public final class ActivityThread extends ClientTransactionHandlerimplements ActivityThreadInternal {private final TransactionExecutor mTransactionExecutor = new TransactionExecutor(this);private class ApplicationThread extends IApplicationThread.Stub {@Overridepublic void scheduleTransaction(ClientTransaction transaction) throws RemoteException {ActivityThread.this.scheduleTransaction(transaction);}} @OverrideTransactionExecutor getTransactionExecutor() {return mTransactionExecutor;}
}class H extends Handler {public void handleMessage(Message msg) {...case EXECUTE_TRANSACTION:final ClientTransaction transaction = (ClientTransaction) msg.obj;mTransactionExecutor.execute(transaction);}}

源码路径:frameworks/base/core/java/android/app/ClientTransactionHandler.java

 void scheduleTransaction(ClientTransaction transaction) {transaction.preExecute(this);sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);}

execute方法会调用executeCallbacks方法,然后通过ClientTransaction类的getCallbacks方法获取LaunchActivityItem集合,然后调用LaunchActivityItem类的execute和postExecute方法。

源码路径:frameworks/base/core/java/android/app/servertransaction/TransactionExecutor.java

public TransactionExecutor(ClientTransactionHandler clientTransactionHandler) {mTransactionHandler = clientTransactionHandler;
}
public void execute(ClientTransaction transaction) {if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "Start resolving transaction");...executeCallbacks(transaction);executeLifecycleState(transaction);mPendingActions.clear();if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "End resolving transaction");}
public void executeCallbacks(ClientTransaction transaction) {//获取LaunchActivityItem集合final List<ClientTransactionItem> callbacks = transaction.getCallbacks();...final int size = callbacks.size();for (int i = 0; i < size; ++i) {final ClientTransactionItem item = callbacks.get(i);if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "Resolving callback: " + item);final int postExecutionState = item.getPostExecutionState();final int closestPreExecutionState = mHelper.getClosestPreExecutionState(r,item.getPostExecutionState());if (closestPreExecutionState != UNDEFINED) {cycleToPath(r, closestPreExecutionState, transaction);}//处理启动Activityitem.execute(mTransactionHandler, token, mPendingActions);item.postExecute(mTransactionHandler, token, mPendingActions);if (r == null) {// Launch activity request will create an activity record.r = mTransactionHandler.getActivityClient(token);}}}

execute方法创建了ActivityClientRecord对象,client类型为ActivityThread,因为创建TransactionExecutor上下文是ActivityThread,然后调用ActivityThread类的handleLaunchActivity。

源码路径:frameworks/base/core/java/android/app/servertransaction/LaunchActivityItem.java

public class LaunchActivityItem extends ClientTransactionItem {@Overridepublic void execute(ClientTransactionHandler client, IBinder token,PendingTransactionActions pendingActions) {Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStart");//创建ActivityClientRecordActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState,mPendingResults, mPendingNewIntents, mActivityOptions, mIsForward, mProfilerInfo,client, mAssistToken, mShareableActivityToken, mLaunchedFromBubble,mTaskFragmentToken);//处理启动Activityclient.handleLaunchActivity(r, pendingActions, null /* customIntent */);Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);}@Overridepublic void postExecute(ClientTransactionHandler client, IBinder token,PendingTransactionActions pendingActions) {//启动Activity数量client.countLaunchingActivities(-1);}
}

handleLaunchActivity方法中调用performLaunchActivity方法,它是真正启动Activity的方法,首先创建了appContext,通过类加载器创建Activity,创建Application,调用Activity的attach方法将一些数据如context传递给Activity。

Activity Context具体类型为ContextImpl,Activity类的attach方法中调用了attachBaseContext方法给ContextWrapper类中的mBase赋值,这就验证了开始说到的为什么startActivity的最终实现在ContextImpl类中。

最后开始Activity的第一个生命周期方法onCreate,调用Instrumentation类的callActivityOnCreate方法,最终调用Activity类的performCreate方法,在performCreate方法中会调用Activity的onCreate方法,到这里,Activity就被启动了。

	@Overridepublic Activity handleLaunchActivity(ActivityClientRecord r,PendingTransactionActions pendingActions, Intent customIntent) {...//真正启动Activity的方法final Activity a = performLaunchActivity(r, customIntent);return a;}
private ContextImpl createBaseContextForActivity(ActivityClientRecord r) {final int displayId = ActivityClient.getInstance().getDisplayId(r.token);ContextImpl appContext = ContextImpl.createActivityContext(this, r.packageInfo, r.activityInfo, r.token, displayId, r.overrideConfig);...return appContext;}
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {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);}//app context创建,这里也可以证明Activity Context具体类型为ContextImplContextImpl appContext = createBaseContextForActivity(r);Activity activity = null;try {java.lang.ClassLoader cl = appContext.getClassLoader();//类加载器创建Activityactivity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);StrictMode.incrementExpectedActivityCount(activity.getClass());r.intent.setExtrasClassLoader(cl);r.intent.prepareToEnterProcess(isProtectedComponent(r.activityInfo),appContext.getAttributionSource());if (r.state != null) {r.state.setClassLoader(cl);}...try {//有则缓存读取Application,没有创建ApplicationApplication app = r.packageInfo.makeApplicationInner(false, mInstrumentation);synchronized (mResourcesManager) {mActivities.put(r.token, r);}if (activity != null) {CharSequence ,title = r.activityInfo.loadLabel(appContext.getPackageManager());Configuration config =new Configuration(mConfigurationController.getCompatConfiguration());if (r.overrideConfig != null) {config.updateFrom(r.overrideConfig);}if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "+ r.activityInfo.name + " with config " + config);Window window = null;if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {window = r.mPendingRemoveWindow;r.mPendingRemoveWindow = null;r.mPendingRemoveWindowManager = null;}// Activity resources must be initialized with the same loaders as the// application context.appContext.getResources().addLoaders(app.getResources().getLoaders().toArray(new ResourcesLoader[0]));appContext.setOuterContext(activity);//appContext传递给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.activityConfigCallback,r.assistToken, r.shareableActivityToken);if (customIntent != null) {activity.mIntent = customIntent;}r.lastNonConfigurationInstances = null;checkAndBlockForNetworkAccess();activity.mStartedActivity = false;int theme = r.activityInfo.getThemeResource();//设置主题if (theme != 0) {activity.setTheme(theme);}r.activity = activity;//调用Activity的onCreate回调,进入Activity生命周期的onCreate阶段if (r.isPersistable()) {mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);} else {mInstrumentation.callActivityOnCreate(activity, r.state);}}//设置Activity的state为onCreate,r.setState(ON_CREATE);return activity;}
public void callActivityOnCreate(Activity activity, Bundle icicle,PersistableBundle persistentState) {prePerformCreate(activity);activity.performCreate(icicle, persistentState);postPerformCreate(activity);}

源码路径:frameworks/base/core/java/android/app/Activity.java

final void attach(Context context, ActivityThread aThread,Instrumentation instr, IBinder token, int ident,Application application, Intent intent, ActivityInfo info,CharSequence title, Activity parent, String id,NonConfigurationInstances lastNonConfigurationInstances,Configuration config, String referrer, IVoiceInteractor voiceInteractor,Window window, ActivityConfigCallback activityConfigCallback, IBinder assistToken,IBinder shareableActivityToken) {//mBase赋值attachBaseContext(context);
}
final void performCreate(Bundle icicle, PersistableBundle persistentState) {...if (persistentState != null) {onCreate(icicle, persistentState);} else {onCreate(icicle)}
}
进程调用

根Activity(应用)启动过程中进程调用时序图如下。普通Activity只涉及AMS所在进程(Systemserver)和应用程序进程。

应用启动进程调用时序图

补充

消息循环创建过程

创建应用程序进程后,进入ActivityThread类的main方法,main方法中首先创建主线程Looper,然后判断Handler类型的sMainThreadHandler是否为null,为null则获取H类,H类继承于Handler,是ActivityThread的内部类,用于处理主线程的消息循环。H类的handleMessage方法中可以发现做了大量生命周期的处理工作,因此可以看出Activity 生命周期不过就是Looper传递消息中的某一个而已。最后调用Looper的loop方法,使得Looper开始处理消息。Looper类的loop方法中存在一个死循环。

可以看出,系统在应用程序进程启动完成后就会创建一个消息循环,这样运行在应用程序进程中的应用程序可以方便的使用消息处理机制。

源码路径:frameworks\base\core\java\android\app\ActivityThread.java

static volatile Handler sMainThreadHandler;
final H mH = new H();
public static void main(String[] args) {...//创建主线程LooperLooper.prepareMainLooper();ActivityThread thread = new ActivityThread();thread.attach(false, startSeq);if (sMainThreadHandler == null) {//绑定主线程H类sMainThreadHandler = thread.getHandler();}if (false) {Looper.myLooper().setMessageLogging(newLogPrinter(Log.DEBUG, "ActivityThread"));}// End of event ActivityThreadMain.Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);//Looper开始工作Looper.loop();throw new RuntimeException("Main thread loop unexpectedly exited");    
}
public Handler getHandler() {return mH;
}
class H extends Handler {...public void handleMessage(Message msg) {case RELAUNCH_ACTIVITY:handleRelaunchActivityLocally((IBinder) msg.obj);case EXIT_APPLICATION:if (mInitialApplication != null) {mInitialApplication.onTerminate();}Looper.myLooper().quit();break;...}
}

源码路径:frameworks\base\core\java\android\os\Looper.java

final MessageQueue mQueue;
public static void loop() {...for (;;) {if (!loopOnce(me, ident, thresholdOverride)) {return;}}
}
private static boolean  loopOnce(final Looper me,final long ident, final int thresholdOverride) {//MessageQueue消息队列中取消息,没有消息时,MessageQueue的next方法会阻塞(next方法也存在死循环)Message msg = me.mQueue.next(); // might block...//处理消息, msg.target为发送消息的Handler对象msg.target.dispatchMessage(msg);
}

这里衍生出两个问题:

主线程 Looper.loop() 死循环为何不会ANR

loop方法中当没有消息的时候才会return,然后就会抛出RuntimeException,主线程就会退出,也意味着应用退出了,在没有消息的时候,MessageQueue的next方法会阻塞,因为next方法内部也存在一个死循环,所以正常情况下应用不会退出。

至于为何不会ANR呢?以下四种场景会导致ANR:

InputDispatching Timeout:5秒内无法响应屏幕触摸事件或键盘输入事件。
BroadcastQueue Timeout :在执行前台广播(BroadcastReceiver)的onReceive()函数时10秒没有处理完成,后台为60秒。
Service Timeout:前台服务20秒内,后台服务在200秒内没有执行完毕。
ContentProvider Timeout :ContentProvider的publish在10s内没进行完。

从代码逻辑可以看出来,我们的代码是在循环内执行的,只能说对消息的处理阻塞了loop方法循环,而不是loop方法循环阻塞了它。这里需要注意循环内消息处理时间过长,才会造成ANR,死循环本身不会造成ANR。

Looper.loop()死循环为何不会导致CPU占用率过高

next方法也存在一个死循环,并且会调用JNI方法nativePollOnce。它对应的C函数为android_os_MessageQueue_nativePollOnce

源码路径:frameworks\base\core\java\android\os\MessageQueue.java

private native void nativePollOnce(long ptr, int timeoutMillis); /*non-static for callbacks*/
Message next() {for (;;) {if (nextPollTimeoutMillis != 0) {Binder.flushPendingCommands();}nativePollOnce(ptr, nextPollTimeoutMillis);...
}

最终调用到Looper类的pollInner函数中,调用 epoll_wait,会等待消息,直到有消息后,才会唤醒。阻塞是不会消耗CPU的时间片,不会导致CPU占用率高。总结来说,没有消息时,会一直阻塞在nativePollOnce函数里,此时主线程会释放CPU资源进入休眠状态,知道有消息时,管道写入数据,调用nativeWork方法唤醒,这里涉及到Linux pipe/epoll机制。

源码路径:frameworks\base\core\jni\android_os_MessageQueue.cpp

static void android_os_MessageQueue_nativePollOnce(JNIEnv* env, jobject obj,jlong ptr, jint timeoutMillis) {NativeMessageQueue* nativeMessageQueue = reinterpret_cast<NativeMessageQueue*>(ptr);nativeMessageQueue->pollOnce(env, obj, timeoutMillis);
}
void NativeMessageQueue::pollOnce(JNIEnv* env, jobject pollObj, int timeoutMillis) {mPollEnv = env;mPollObj = pollObj;mLooper->pollOnce(timeoutMillis);mPollObj = NULL;mPollEnv = NULL;if (mExceptionObj) {env->Throw(mExceptionObj);env->DeleteLocalRef(mExceptionObj);mExceptionObj = NULL;}
}

源码路径:system/core/libutils/Looper.cpp

int Looper::pollOnce(int timeoutMillis, int* outFd, int* outEvents, void** outData) {int result = 0;for (;;) {...result = pollInner(timeoutMillis);}
}
int Looper::pollInner(int timeoutMillis) {...struct epoll_event eventItems[EPOLL_MAX_EVENTS];//等待事件发生或者超时,在nativeWake()方法,向管道写端写入字符,则该方法会返回;int eventCount = epoll_wait(mEpollFd.get(), eventItems, EPOLL_MAX_EVENTS, timeoutMillis);
}

总结

Activity的启动过程。其中包含了根Activity(应用程序)启动过程和普通Activity的启动过程,进程之间的调用关系,同时补充了消息循环创建过程,拆解出两个面试常客进行了解析。根Activity启动过程中包含AMS向Zygote进程发送创建应用程序进程请求的逻辑。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/581809.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

加强->servlet->tomcat

0什么是servlet jsp也是servlet 细细体会 Servlet 是 JavaEE 的规范之一&#xff0c;通俗的来说就是 Java 接口&#xff0c;将来我们可以定义 Java 类来实现这个接口&#xff0c;并由 Web 服务器运行 Servlet &#xff0c;所以 TomCat 又被称作 Servlet 容器。 Servlet 提供了…

打造完备数据生态,「开放互信、合作共赢」: 拓数派亮相2023龙蜥操作系统大会

拓数派始终持「开放互信&#xff0c;合作共赢」的理念&#xff0c;通过积极建立合作伙伴生态网络、构建生态工具、打造活跃的技术和用户社区等方式&#xff0c;构筑更加完善的数据生态体系&#xff0c;为用户带来更加便捷的使用体验。2023年12月17-18日&#xff0c;由开放原子开…

如何实现无公网ip环境访问vscode远程开发【内网穿透】

文章目录 前言1、安装 OpenSSH2、vscode 配置 ssh3. 局域网测试连接远程服务器4. 公网远程连接4.1 ubuntu 安装 cpolar 内网穿透4.2 创建隧道映射4.3 测试公网远程连接 5. 配置固定 TCP 端口地址5.1 保留一个固定 TCP 端口地址5.2 配置固定 TCP 端口地址5.3 测试固定公网地址远…

使用Vue3开发学生管理系统模板5 学生家长信息的实现

字段设计 IDname&#xff1a;姓名&#xff0c;字符串&#xff0c;最长36个字符gender&#xff1a;性别&#xff0c;字符串&#xff0c;最长6个字符串age&#xff1a;年龄&#xff0c;数字类型phone&#xff1a;电话&#xff0c;字符串&#xff0c;最长20个字符student_id&…

无需手动搜索!轻松创建IntelliJ IDEA快捷方式的Linux教程

轻松创建IntelliJ IDEA快捷方式的Linux教程 一、IntelliJ IDEA简介二、在Linux系统中创建快捷方式的好处三、命令行创建IntelliJ IDEA快捷方式四、图形界面创建IntelliJ IDEA快捷方式五、常见问题总结 一、IntelliJ IDEA简介 IntelliJ IDEA是一个由JetBrains搞的IDE&#xff0…

搭建FTP服务器详细介绍

一.FTP简介 &#xff11;.&#xff11;什么是FTP &#xff11;.&#xff12;FTP服务器介绍 &#xff11;.&#xff13;FTP服务器优缺点 二.FTP服务器的搭建与配置 2.1 开启防火墙 2.2创建组 2.3创建用户 2.4安装FTP服务器 2.5配置FTP服务器 &#xff12;.&#xff…

麒麟KYLINOS _ 传书 _ 如何传输文件?

原文链接&#xff1a;麒麟KYLINOS | 传书 | 如何传输文件&#xff1f; hello&#xff0c;大家好啊&#xff01;今天我要给大家介绍的是在麒麟KYLINOS操作系统上使用自带的文件传输软件——传书。在日常工作和生活中&#xff0c;我们经常需要在不同设备之间传输文件和信息。传书…

论文阅读《Restormer: Efficient Transformer for High-Resolution Image Restoration》

论文地址:https://openaccess.thecvf.com/content/CVPR2022/html/Zamir_Restormer_Efficient_Transformer_for_High-Resolution_Image_Restoration_CVPR_2022_paper.html 源码地址:https://github.com/swz30/Restormer 概述 图像恢复任务旨在从受到各种扰动(噪声、模糊、雨滴…

账号租号平台PHP源码,支持单独租用或合租使用

源码简介 租号平台源码&#xff0c;采用常见的租号模式。 平台的主要功能如下&#xff1a; 支持单独租用或采用合租模式&#xff1b; 采用易支付通用接口进行支付&#xff1b; 添加邀请返利功能&#xff0c;以便站长更好地推广&#xff1b; 提供用户提现功能&#xff1b;…

超强整理,Web自动化测试-验证码/cookie机制(详全)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 1、后台登录案例 …

Springboot整合Elastic-job

一 概述 Elastic-Job 最开始只有一个 elastic-job-core 的项目&#xff0c;定位轻量级、无中心化&#xff0c;最核心的服务就是支持弹性扩容和数据分片&#xff01;从 2.X 版本以后&#xff0c;主要分为 Elastic-Job-Lite 和 Elastic-Job-Cloud 两个子项目。esjbo官网地址 Ela…

【五】【C语言\动态规划】删除并获得点数、粉刷房子、买卖股票的最佳时机含冷冻期,三道题目深度解析

动态规划 动态规划就像是解决问题的一种策略&#xff0c;它可以帮助我们更高效地找到问题的解决方案。这个策略的核心思想就是将问题分解为一系列的小问题&#xff0c;并将每个小问题的解保存起来。这样&#xff0c;当我们需要解决原始问题的时候&#xff0c;我们就可以直接利…

Docker部署Plik临时文件上传系统并实现远程访问设备上传下载文件

文章目录 1. Docker部署Plik2. 本地访问Plik3. Linux安装Cpolar4. 配置Plik公网地址5. 远程访问Plik6. 固定Plik公网地址7. 固定地址访问Plik 本文介绍如何使用Linux docker方式快速安装Plik并且结合Cpolar内网穿透工具实现远程访问&#xff0c;实现随时随地在任意设备上传或者…

[Angular] 笔记 11:可观察对象(Observable)

chatgpt: 在 Angular 中&#xff0c;Observables 是用于处理异步数据流的重要工具。它们被广泛用于处理从异步操作中获取的数据&#xff0c;比如通过 HTTP 请求获取数据、定时器、用户输入等。Observables 提供了一种机制来订阅这些数据流&#xff0c;并可以在数据到达时执行相…

代码随想录算法训练营day1|704.二分查找、27.移除元素

第一章 数组 part01 今日任务 数组理论基础&#xff0c;704. 二分查找&#xff0c;27. 移除元素 详细布置 数组理论基础 文章链接&#xff1a;代码随想录 题目建议&#xff1a; 了解一下数组基础&#xff0c;以及数组的内存空间地址&#xff0c;数组也没那么简单。 704. 二…

Jupyter Notebook 开启远程登录

Jupyter Notebook可以说是非常好用的小工具&#xff0c;但是不经过配置只能够在本机访问 安装jupyter notebook conda install jupyter notebook 生成默认配置文件 jupyter notebook --generate-config 将会在用户主目录下生成.jupyter文件夹&#xff0c;其中jupyter_noteb…

查看ios app运行日志

摘要 本文介绍了一款名为克魔助手的iOS应用日志查看工具&#xff0c;该工具可以方便地查看iPhone设备上应用和系统运行时的实时日志和奔溃日志。同时还提供了奔溃日志分析查看模块&#xff0c;可以对苹果奔溃日志进行符号化、格式化和分析&#xff0c;极大地简化了开发者的调试…

短说社区运营的使用工具分享(一)

本文是一篇针对短说社区运营的使用工具分享帖&#xff0c;是小编结合日常使用&#xff0c;总结的一些可以帮助网站管理员和运营人员进行日常操作和管理的工具。 1. 想天工作台之运营面板 想天工作台可以将桌面划分不同的类型来辅助办公&#xff0c;我分享下我当前的桌面情况&…

基于Mbed Studio环境下开发STM32

基于Mbed Studio环境下开发STM32 &#x1f4cd;Mbed官网&#xff1a;https://os.mbed.com/ ✨mbed OS是ARM出的一个免费开源的&#xff0c;面向物联网的操作系统。提供了一个定义良好的API来开发C应用程序&#xff1b;集成度很高&#xff0c;类似Arduino&#xff0c;目前并不兼…

新兴品牌如何做好传播?媒介盒子分享三招

很多品牌抓住了品类和流量红利&#xff0c;给自己做了传播&#xff0c;但是红利是有时效的&#xff0c;流量越来越贵&#xff0c;竞争对手你追我赶&#xff0c;只有真正占领用户心智&#xff0c;才能获取长期利润。今天媒介盒子就来和大家聊聊&#xff1a;新兴品牌如何做好传播…