网站服务器的功能,上海建设网站是多少,最新招商代理项目,网站建设费算什么费用1 冷启动与热启动
应用启动分为冷启动和热启动。
冷启动#xff1a;点击桌面图标#xff0c;手机系统不存在该应用进程#xff0c;这时系统会重新fork一个子进程来加载Application并启动Activity#xff0c;这个启动方式就是冷启动。 热启动#xff1a;应用的热启动比冷…1 冷启动与热启动
应用启动分为冷启动和热启动。
冷启动点击桌面图标手机系统不存在该应用进程这时系统会重新fork一个子进程来加载Application并启动Activity这个启动方式就是冷启动。 热启动应用的热启动比冷启动简单得多开销也更低。在热启动中因为系统里已有该应用的进程所以系统的所有工作就是将Activity 带到前台。
2 Activity的启动流程
2.1 启动准备
当我们点击Launcher上的应用图标时最终会调用到activity的startActivity()函数。我们就从activity的startActivity()开始。
Override
public void startActivity(Intent intent, Nullable Bundle options) {getAutofillClientController().onStartActivity(intent, mIntent);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);}
}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());}} else {}
}这里调到了Instrumentation.execStartActivity。
Instrumentation 负责调用 Activity 和 Application 的生命周期具有跟踪 Application 和 Activity 生命周期的功能。
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(),nwho.getAttributionTag(), intent,intent.resolveTypeIfNeeded(who.getContentResolver()), token, target ! null ? target.mEmbeddedID : null,requestCode, 0, null, options);notifyStartActivityResult(result, options);checkStartActivityResult(result, intent);} catch (RemoteException e) {throw new RuntimeException(Failure from system, e);}
}调用了 ActivityTaskManager.getService() 方法来获取 ATMS 的代理对象接着调用了它的 startActivity 方法。
ActivityTaskManager是实现 Activity 与 ATMS 跨进程交互的接口ATMS 的辅助类。
而ActivityTaskManagerService是管理 Activity 以及其容器task、stacks、displays的系统服务负责 Activity 管理和调度工作Android 10 中新增。ATMS 是 AMS 的一个辅助类分担了 AMS 的一部分功能继承自 IActivityTaskManager.Stub。
Override
public 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());
}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) {...return getActivityStartController().obtainStarter(intent, startActivityAsUser).setCaller(caller).setCallingPackage(callingPackage).setCallingFeatureId(callingFeatureId).setResolvedType(resolvedType).setResultTo(resultTo).setResultWho(resultWho).setRequestCode(requestCode).setStartFlags(startFlags).setProfilerInfo(profilerInfo).setActivityOptions(opts).setUserId(userId).execute();
}ActivityStartController 是用于 Activity 启动的控制器。 通过调用其 obtainStarter 方法来获取 ActivityStarter 对象
ActivityStarter obtainStarter(Intent intent, String reason) {return mFactory.obtain().setIntent(intent).setReason(reason);
}ActivityStarter 是 Android 7.0 中新加入的类是 Activity 的控制器讲如何启动一个 Activity会收集所有的逻辑来决定如何将 Intent 和 Flags 转换为 Activity并将 Activity 和 Task 以及 Stack 相关联。
//framework/base/services/core/java/com/android/server/wm/ActivityStarter.java
/*** Controller for interpreting how and then launching an activity.** This class collects all the logic for determining how an intent and flags should be turned into* an activity and associated task and root task.*/
class ActivityStarter {}2.2 ActivityRecord的创建
看看ActivityStarter的execute()是如何执行的。
/*** Resolve necessary information according the request parameters provided earlier, and execute* the request which begin the journey of starting an activity.* return The starter result.*/
int execute() {try {onExecutionStarted();...try {res executeRequest(mRequest);} finally {mRequest.logMessage.append( result code).append(res);Slog.i(TAG, mRequest.logMessage.toString());mRequest.logMessage.setLength(0);}...} finally {onExecutionComplete();}
}
/*** Executing activity start request and starts the journey of starting an activity. Here* begins with performing several preliminary checks. The normally activity launch flow will* go through {link #startActivityUnchecked} to {link #startActivityInner}.*/
private int executeRequest(Request request) {...final ActivityRecord r new ActivityRecord.Builder(mService).setCaller(callerApp).setLaunchedFromPid(callingPid).setLaunchedFromUid(callingUid).setLaunchedFromPackage(callingPackage).setLaunchedFromFeature(callingFeatureId).setIntent(intent).setResolvedType(resolvedType).setActivityInfo(aInfo).setConfiguration(mService.getGlobalConfiguration()).setResultTo(resultRecord).setResultWho(resultWho).setRequestCode(requestCode).setComponentSpecified(request.componentSpecified).setRootVoiceInteraction(voiceSession ! null).setActivityOptions(checkedOptions).setSourceRecord(sourceRecord).build();mLastStartActivityRecord r;mLastStartActivityResult startActivityUnchecked(r, sourceRecord, voiceSession,request.voiceInteractor, startFlags, checkedOptions,inTask, inTaskFragment, balCode, intentGrants, realCallingUid);return mLastStartActivityResult;
}这里创建了新activity的ActivityRecord对象然后调用startActivityUnchecked。
2.3 Task的创建
/*** Start an activity while most of preliminary checks has been done and caller has been* confirmed that holds necessary permissions to do so.* Here also ensures that the starting activity is removed if the start wasnt successful.*/
private int startActivityUnchecked(final ActivityRecord r,ActivityRecord sourceRecord,IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags, ActivityOptions options, Task inTask, TaskFragment inTaskFragment,BalCode int balCode, NeededUriGrants intentGrants, int realCallingUid) {result startActivityInner(r, sourceRecord, voiceSession, voiceInteractor,startFlags, options, inTask, inTaskFragment, balCode,intentGrants, realCallingUid);
}/*** Start an activity and determine if the activity should be adding to the top of an existing* task or delivered new intent to an existing activity. Also manipulating the activity task* onto requested or valid root-task/display.** Note: This method should only be called from {link #startActivityUnchecked}.*/// TODO(b/152429287): Make it easier to exercise code paths through startActivityInner
VisibleForTesting
int startActivityInner(final ActivityRecord r, ActivityRecord sourceRecord,IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,int startFlags, ActivityOptions options, Task inTask,TaskFragment inTaskFragment, BalCode int balCode,NeededUriGrants intentGrants, int realCallingUid) {...// Compute if there is an existing task that should be used for.final Task targetTask reusedTask ! null ? reusedTask : computeTargetTask();final boolean newTask targetTask null;mTargetTask targetTask;...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);}...final boolean isTaskSwitch startedTask ! prevTopTask;mTargetRootTask.startActivityLocked(mStartActivity, topRootTask, newTask,isTaskSwitch, mOptions, sourceRecord);if (mDoResume) {...} else {mRootWindowContainer.resumeFocusedTasksTopActivities(mTargetRootTask, mStartActivity, mOptions, mTransientLaunch);}mRootWindowContainer.updateUserRootTask(mStartActivity.mUserId, mTargetRootTask);// Update the recent tasks list immediately when the activity startsmSupervisor.mRecentTasks.add(startedTask);mSupervisor.handleNonResizableTaskIfNeeded(startedTask, mPreferredWindowingMode,mPreferredTaskDisplayArea, mTargetRootTask);...
}这里reusedTask明显是null我们走的是computeTargetTask()。先来看computeTargetTask
/** Returns the leaf task where the target activity may be placed. */
private Task computeTargetTask() {if (mStartActivity.resultTo null mInTask null !mAddingToTask (mLaunchFlags FLAG_ACTIVITY_NEW_TASK) ! 0) {// A new task should be created instead of using existing one.return null;} else if (mSourceRecord ! null) {return mSourceRecord.getTask();} else if (mInTask ! null) {// The task is specified from AppTaskImpl, so it may not be attached yet.if (!mInTask.isAttached()) {// Attach the task to display area. Ignore the returned root task (though usually// they are the same) because target task should be leaf task.getOrCreateRootTask(mStartActivity, mLaunchFlags, mInTask, mOptions);}return mInTask;} else {final Task rootTask getOrCreateRootTask(mStartActivity, mLaunchFlags, null /* task */,mOptions);final ActivityRecord top rootTask.getTopNonFinishingActivity();if (top ! null) {return top.getTask();} else {// Remove the root task if no activity in the root task.rootTask.removeIfPossible(computeTargetTask);}}return null;
}启动根 Activity 时会将 Intent 的 Flag 设置为 FLAG_ACTIVITY_NEW_TASK表示要创建一个新的 Task这里返回null。因此final boolean newTask targetTask null;这句就是true。
然后判断mTargetRootTask是否为空也就是TaskDisplayArea。
接着就到了setNewTask(taskToAffiliate);
private void setNewTask(Task taskToAffiliate) {final boolean toTop !mLaunchTaskBehind !mAvoidMoveToFront;final Task task mTargetRootTask.reuseOrCreateTask(mStartActivity.info, mIntent, mVoiceSession,mVoiceInteractor, toTop, mStartActivity, mSourceRecord, mOptions);task.mTransitionController.collectExistenceChange(task);addOrReparentStartingActivity(task, setTaskFromReuseOrCreateNewTask);ProtoLog.v(WM_DEBUG_TASKS, Starting new activity %s in new task %s,mStartActivity, mStartActivity.getTask());if (taskToAffiliate ! null) {mStartActivity.setTaskToAffiliateWith(taskToAffiliate);}
}Task 就是用户在执行某项工作时与之相关联的 Activity 集合。系统通过任务栈来管理这些 Activity它们按照打开的顺序进入任务栈中。这些 Activity 可以来自同一个 APP也可以来自不同的 APPActivity 之间不一定非要有关联。
比如当我们点recent键或者上滑进入Recent界面时屏幕上展示的就是一个个的 Task。
class Task extends TaskFragment {
}
class TaskFragment extends WindowContainerWindowContainer {
}Task继承TaskFragment而TaskFragment是一个容器可以用来放 activities 或者其它的 TaskFragment也能够管理 activity 的生命周期或者更新 * activities 的可见性。
task affinity在 manifest 文件中注册 activity 时如果不申明 taskAffinity 属性就是 APP 程序的默认包名默认情况下一个 APP 中所有的 Activity 都在一个 Task 中
activityandroid:taskAffinity...
/接着调用task的startActivityLocked调用的是 RootWindowContainer.resumeFocusedTasksTopActivities 方法
先来看startActivityLocked。
void startActivityLocked(ActivityRecord r, Nullable Task topTask, boolean newTask,boolean isTaskSwitch, ActivityOptions options, Nullable ActivityRecord sourceRecord) {...boolean doShow true;if (newTask) {if ((r.intent.getFlags() Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) ! 0) {resetTaskIfNeeded(r, r);doShow topRunningNonDelayedActivityLocked(null) r;}} else if (options ! null options.getAnimationType() ActivityOptions.ANIM_SCENE_TRANSITION) {doShow false;}if (options ! null options.getDisableStartingWindow()) {doShow false;}if (r.mLaunchTaskBehind) {// Dont do a starting window for mLaunchTaskBehind. More importantly make sure we// tell WindowManager that r is visible even though it is at the back of the root// task.r.setVisibility(true);ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);// If launching behind, the app will start regardless of whats above it, so mark it// as unknown even before prior pause. This also prevents a race between set-ready// and activityPause. Launch-behind is basically only used for dream now.if (!r.isVisibleRequested()) {r.notifyUnknownVisibilityLaunchedForKeyguardTransition();}// Go ahead to execute app transition for this activity since the app transition// will not be triggered through the resume channel.mDisplayContent.executeAppTransition();} else if (SHOW_APP_STARTING_PREVIEW doShow) {// Figure out if we are transitioning from another activity that is// has the same starting icon as the next one. This allows the// window manager to keep the previous window it had previously// created, if it still had one.Task baseTask r.getTask();final ActivityRecord prev baseTask.getActivity(a - a.mStartingData ! null a.showToCurrentUser());mWmService.mStartingSurfaceController.showStartingWindow(r, prev, newTask,isTaskSwitch, sourceRecord);}
}这里走的是mWmService.mStartingSurfaceController.showStartingWindow也就是显示闪屏页。
继续看startActivityInner对于我们新启动的activity来说mDoResume肯定是false因此走的是else 分支。
//framework/base/services/core/java/com/android/server/wm/Task.java
mRootWindowContainer.resumeFocusedTasksTopActivities(mTargetRootTask, mStartActivity, mOptions, mTransientLaunch);继续到RootWindowContainer.resumeFocusedTasksTopActivities
//framework/base/services/core/java/com/android/server/wm/RootWindowContainer.java
boolean resumeFocusedTasksTopActivities(Task targetRootTask, ActivityRecord target, ActivityOptions targetOptions, boolean deferPause) {boolean result false;if (targetRootTask ! null (targetRootTask.isTopRootTaskInDisplayArea()|| getTopDisplayFocusedRootTask() targetRootTask)) {result targetRootTask.resumeTopActivityUncheckedLocked(target, targetOptions, deferPause);}
}这里targetRootTask是一个task。
/*** Ensure that the top activity in the root task is resumed.** param prev The previously resumed activity, for when in the process* of pausing; can be null to call from elsewhere.* param options Activity options.* param deferPause When {code true}, this will not pause back tasks.** return Returns true if something is being resumed, or false if* nothing happened.** NOTE: It is not safe to call this method directly as it can cause an activity in a* non-focused root task to be resumed.* Use {link RootWindowContainer#resumeFocusedTasksTopActivities} to resume the* right activity for the current system state.*/
GuardedBy(mService)
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev,ActivityOptions options, boolean deferPause) {if (isLeafTask()) {if (isFocusableAndVisible()) {someActivityResumed resumeTopActivityInnerLocked(prev, options, deferPause);}}
}GuardedBy(mService)
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options, boolean deferPause) {resumed[0] topFragment.resumeTopActivity(prev, options, deferPause);return resumed[0];
}继续到TaskFragment的resumeTopActivity。
2.4 启动进程
final boolean resumeTopActivity(ActivityRecord prev, ActivityOptions options,boolean deferPause) {boolean pausing !deferPause taskDisplayArea.pauseBackTasks(next);if (mResumedActivity ! null) {ProtoLog.d(WM_DEBUG_STATES, resumeTopActivity: Pausing %s,mResumedActivity);pausing | startPausing(mTaskSupervisor.mUserLeaving, false /* uiSleeping */,next, resumeTopActivity);}
}首先通知当前的activity走Pause逻辑。
if (pausing) {if (next.attachedToProcess()) {next.app.updateProcessInfo(false /* updateServiceConnectionActivities */,true /* activityChange */, false /* updateOomAdj */,false /* addPendingTopUid */);} else if (!next.isProcessRunning()) {// Since the start-process is asynchronous, if we already know the process of next// activity isnt running, we can start the process earlier to save the time to wait// for the current activity to be paused.final boolean isTop this taskDisplayArea.getFocusedRootTask();mAtmService.startProcessAsync(next, false /* knownToBeDead */, isTop,isTop ? HostingRecord.HOSTING_TYPE_NEXT_TOP_ACTIVITY: HostingRecord.HOSTING_TYPE_NEXT_ACTIVITY);}
}如果要启动activity的进程没有启动就先调用ATMS的startProcessAsync启动进程。
void startProcessAsync(ActivityRecord activity, boolean knownToBeDead, boolean isTop,String hostingType) {// 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);
}继续走AMS的startProcess
Override
public void startProcess(String processName, ApplicationInfo info, boolean knownToBeDead, boolean isTop, String hostingType,ComponentName hostingName) {synchronized (ActivityManagerService.this) {// If the process is known as top app, set a hint so when the process is// started, the top priority can be applied immediately to avoid cpu being// preempted by other processes before attaching the process of top app.startProcessLocked(processName, info, knownToBeDead, 0 /* intentFlags */,new HostingRecord(hostingType, hostingName, isTop),ZYGOTE_POLICY_FLAG_LATENCY_SENSITIVE, false /* allowWhileBooting */,false /* isolated */);}
}GuardedBy(this)
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
GuardedBy(mService)
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) {checkSlow(startTime, startProcess: stepping in to startProcess);final boolean success startProcessLocked(app, hostingRecord, zygotePolicyFlags, abiOverride);checkSlow(startTime, startProcess: done starting proc!);return success ? app : null;
}GuardedBy(mService)
boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,int zygotePolicyFlags, boolean disableHiddenApiChecks, boolean disableTestApiChecks, String abiOverride) {return startProcessLocked(hostingRecord, entryPoint, app, uid, gids,runtimeFlags, zygotePolicyFlags, mountExternal, seInfo, requiredAbi,instructionSet, invokeWith, startUptime, startElapsedTime);
}这里startProcessLocked比较长主要是为进程启动根据条件来添加参数。
GuardedBy(mService)
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 cant 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()});// By now the process group should have been created by zygote.app.mProcessGroupCreated true;}
}直接看appZygote.getProcess().start
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 MapString, PairString, LongpkgDataInfoMap,Nullable MapString, PairString, LongallowlistedDataInfoList,boolean bindMountAppsData,boolean bindMountAppStorageDirs,Nullable String[] zygoteArgs) {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() {synchronized(mLock) {// The USAP pool can not be used if the application will not use// the systems graphics driver. If that driver is requested // use the Zygote application start path.return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi),zygotePolicyFlags, argsForZygote);}
}这个过程创建了Socket然后连接zygote通过socket完成AMS和Zygote之间的通讯。
// frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java
Runnable processCommand(ZygoteServer zygoteServer, boolean multipleOK) {ZygoteArguments parsedArgs;try (ZygoteCommandBuffer argBuffer new ZygoteCommandBuffer(mSocket)) {while (true) {try {parsedArgs ZygoteArguments.getInstance(argBuffer);// Keep argBuffer around, since we need it to fork.} catch (IOException ex) {throw new IllegalStateException(IOException on command socket, ex);}...if (parsedArgs.mInvokeWith ! null || parsedArgs.mStartChildZygote|| !multipleOK || peer.getUid() ! Process.SYSTEM_UID) {// Continue using old code for now. TODO: Handle these cases in the other path.pid Zygote.forkAndSpecialize(parsedArgs.mUid, parsedArgs.mGid,parsedArgs.mGids, parsedArgs.mRuntimeFlags, rlimits,parsedArgs.mMountExternal, parsedArgs.mSeInfo, parsedArgs.mNiceName,fdsToClose, fdsToIgnore, parsedArgs.mStartChildZygote,parsedArgs.mInstructionSet, parsedArgs.mAppDataDir,parsedArgs.mIsTopApp, parsedArgs.mPkgDataInfoList,parsedArgs.mAllowlistedDataInfoList, parsedArgs.mBindMountAppDataDirs,parsedArgs.mBindMountAppStorageDirs); // 1try {if (pid 0) {// in childzygoteServer.setForkChild();zygoteServer.closeServerSocket();IoUtils.closeQuietly(serverPipeFd);serverPipeFd null;return handleChildProc(parsedArgs, childPipeFd,parsedArgs.mStartChildZygote); // 2} else {...}} finally {...}} else {...}}}...throw new AssertionError(Shouldnt get here);
}private Runnable handleChildProc(ZygoteArguments parsedArgs,FileDescriptor pipeFd, boolean isZygote) {...if (parsedArgs.mInvokeWith ! null) {...} else {if (!isZygote) { // 3 isZygote 一般是 falsereturn ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,parsedArgs.mDisabledCompatChanges,parsedArgs.mRemainingArgs, null /* classLoader */); // 4} else {return ZygoteInit.childZygoteInit(parsedArgs.mRemainingArgs /* classLoader */); // }}
}注释 3 处的 isZygote 一般是 false注释 4 处调用的是 ZygoteInit.zygoteInit 方法
// frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public static Runnable zygoteInit(int targetSdkVersion, long[] disabledCompatChanges,String[] argv, ClassLoader classLoader) {if (RuntimeInit.DEBUG) {Slog.d(RuntimeInit.TAG, RuntimeInit: Starting application from zygote);}Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, ZygoteInit);RuntimeInit.redirectLogStreams();RuntimeInit.commonInit();ZygoteInit.nativeZygoteInit();return RuntimeInit.applicationInit(targetSdkVersion, disabledCompatChanges, argv,classLoader); // 1
}注释 1 处调用 RuntimeInit.applicationInit 方法
protected static Runnable applicationInit(int targetSdkVersion, long[] disabledCompatChanges,String[] argv, ClassLoader classLoader) {// If the application calls System.exit(), terminate the process// immediately without running any shutdown hooks. It is not possible to// shutdown an Android application gracefully. Among other things, the// Android runtime shutdown hooks close the Binder driver, which can cause// leftover running threads to crash before the process actually exits.nativeSetExitWithoutCleanup(true);VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);VMRuntime.getRuntime().setDisabledCompatChanges(disabledCompatChanges);final Arguments args new Arguments(argv);// The end of of the RuntimeInit event (see #zygoteInit).Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);// Remaining arguments are passed to the start classs static mainreturn findStaticMain(args.startClass, args.startArgs, classLoader);
}/*** Invokes a static main(argv[]) method on class className.* Converts various failing exceptions into RuntimeExceptions, with* the assumption that they will then cause the VM instance to exit.** param className Fully-qualified class name* param argv Argument vector for main()* param classLoader the classLoader to load {className} with*/
protected static Runnable findStaticMain(String className, String[] argv,ClassLoader classLoader) {Class? cl;try {cl Class.forName(className, true, classLoader);} catch (ClassNotFoundException ex) {throw new RuntimeException(Missing class when invoking static main className,ex);}Method m;try {m cl.getMethod(main, new Class[] { String[].class });} catch (NoSuchMethodException ex) {throw new RuntimeException(Missing static main on className, ex);} catch (SecurityException ex) {throw new RuntimeException(Problem getting static main on className, ex);}int modifiers m.getModifiers();if (! (Modifier.isStatic(modifiers) Modifier.isPublic(modifiers))) {throw new RuntimeException(Main method is not public and static on className);}/** This throw gets caught in ZygoteInit.main(), which responds* by invoking the exceptions run() method. This arrangement* clears up all the stack frames that were required in setting* up the process.*/return new MethodAndArgsCaller(m, argv);
}/*** Helper class which holds a method and arguments and can call them. * This is used as part of* a trampoline to get rid of the initial process setup stack frames.*/
static class MethodAndArgsCaller implements Runnable {/** method to call */private final Method mMethod;/** argument array */private final String[] mArgs;public MethodAndArgsCaller(Method method, String[] args) {mMethod method;mArgs args;}public void run() {try {mMethod.invoke(null, new Object[] { mArgs });} catch (IllegalAccessException ex) {throw new RuntimeException(ex);} catch (InvocationTargetException ex) {Throwable cause ex.getCause();if (cause instanceof RuntimeException) {throw (RuntimeException) cause;} else if (cause instanceof Error) {throw (Error) cause;}throw new RuntimeException(ex);}}
}MethodAndArgsCaller.run 方法最终会进入到 ActivityThread.main 方法中。
2.5 ActivityThread创建
public static void main(String[] args) {Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, ActivityThreadMain);// Install selective syscall interceptionAndroidOs.install();// CloseGuard defaults to true and can be quite spammy. We// disable it here, but selectively enable it later (via// StrictMode) on debug builds, but using DropBox, not logs.CloseGuard.setEnabled(false);Environment.initForCurrentUser();// Make sure TrustedCertificateStore looks in the right place for CA certificatesfinal File configDir Environment.getUserConfigDirectory(UserHandle.myUserId());TrustedCertificateStore.setDefaultUserDirectory(configDir);// Call per-process mainline module initialization.initializeMainlineModules();Process.setArgV0(pre-initialized);Looper.prepareMainLooper();// Find the value for {link #PROC_START_SEQ_IDENT} if provided on the command line.// It will be in the format seq114long startSeq 0;if (args ! null) {for (int i args.length - 1; i 0; --i) {if (args[i] ! null args[i].startsWith(PROC_START_SEQ_IDENT)) {startSeq Long.parseLong(args[i].substring(PROC_START_SEQ_IDENT.length()));}}}ActivityThread thread new ActivityThread();thread.attach(false, startSeq);if (sMainThreadHandler null) {sMainThreadHandler thread.getHandler();}if (false) {Looper.myLooper().setMessageLogging(newLogPrinter(Log.DEBUG, ActivityThread));}// End of event ActivityThreadMain.Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);Looper.loop();throw new RuntimeException(Main thread loop unexpectedly exited);
}2.6 attachApplication
继续到ActivityThread#attachthread.attach(false, startSeq);
private void attach(boolean system, long startSeq) {final IActivityManager mgr ActivityManager.getService();try {mgr.attachApplication(mAppThread, startSeq);} catch (RemoteException ex) {throw ex.rethrowFromSystemServer();}
}走到了AMS的attachApplication
Override
public 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);}
}GuardedBy(this)
private void attachApplicationLocked(NonNull IApplicationThread thread,int pid, int callingUid, long startSeq) {final ActiveInstrumentation instr2 app.getActiveInstrumentation();if (app.getIsolatedEntryPoint() ! null) {} else if (instr2 ! null) {thread.bindApplication(processName, appInfo,app.sdkSandboxClientAppVolumeUuid, app.sdkSandboxClientAppPackage,providerList,instr2.mClass,profilerInfo, instr2.mArguments,instr2.mWatcher,instr2.mUiAutomationConnection, 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());} else {thread.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 (!mConstants.mEnableWaitForFinishAttachApplication) {finishAttachApplicationInner(startSeq, callingUid, pid);} else {app.setPendingFinishAttach(true);}
}继续看ApplicationThread#bindApplication
Override
public final void bindApplication(String processName, ApplicationInfo appInfo,String sdkSandboxClientAppVolumeUuid, String sdkSandboxClientAppPackage,ProviderInfoList providerList, ComponentName instrumentationName,ProfilerInfo profilerInfo, Bundle instrumentationArgs,IInstrumentationWatcher instrumentationWatcher,IUiAutomationConnection instrumentationUiConnection, int debugMode,boolean enableBinderTracking, boolean trackAllocation,boolean isRestrictedBackupMode, boolean persistent,Configuration config,CompatibilityInfo compatInfo, Map services, Bundle coreSettings,String buildSerial, AutofillOptions autofillOptions,ContentCaptureOptions contentCaptureOptions, long[] disabledCompatChanges,SharedMemory serializedSystemFontMap,long startRequestedElapsedTime, long startRequestedUptime) {AppBindData data new AppBindData();data.processName processName;data.appInfo appInfo;data.sdkSandboxClientAppVolumeUuid sdkSandboxClientAppVolumeUuid;data.sdkSandboxClientAppPackage sdkSandboxClientAppPackage;data.providers providerList.getList();data.instrumentationName instrumentationName;data.instrumentationArgs instrumentationArgs;data.instrumentationWatcher instrumentationWatcher;data.instrumentationUiAutomationConnection instrumentationUiConnection;data.debugMode debugMode;data.enableBinderTracking enableBinderTracking;data.trackAllocation trackAllocation;data.restrictedBackupMode isRestrictedBackupMode;data.persistent persistent;data.config config;data.compatInfo compatInfo;data.initProfilerInfo profilerInfo;data.buildSerial buildSerial;data.autofillOptions autofillOptions;data.contentCaptureOptions contentCaptureOptions;data.disabledCompatChanges disabledCompatChanges;data.mSerializedSystemFontMap serializedSystemFontMap;data.startRequestedElapsedTime startRequestedElapsedTime;data.startRequestedUptime startRequestedUptime;updateCompatOverrideScale(compatInfo);CompatibilityInfo.applyOverrideScaleIfNeeded(config);sendMessage(H.BIND_APPLICATION, data);
}public void handleMessage(Message msg) {if (DEBUG_MESSAGES) Slog.v(TAG, handling: codeToString(msg.what));switch (msg.what) {case BIND_APPLICATION:Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,bindApplication);AppBindData data (AppBindData)msg.obj;handleBindApplication(data);Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);break;}
}继续看handleBindApplication
// frameworks/base/core/java/android/app/ActivityThread.java
private void handleBindApplication(AppBindData data) {...// send up app name; do this *before* waiting for debuggerProcess.setArgV0(data.processName);android.ddm.DdmHandleAppName.setAppName(data.processName,data.appInfo.packageName,UserHandle.myUserId());VMRuntime.setProcessPackageName(data.appInfo.packageName);// Pass data directory path to ART. This is used for caching information and// should be set before any application code is loaded.VMRuntime.setProcessDataDirectory(data.appInfo.dataDir);if (mProfiler.profileFd ! null) {mProfiler.startProfiling();}...// Instrumentation info affects the class loader, so load it before// setting up the app context.final InstrumentationInfo ii;if (data.instrumentationName ! null) {ii prepareInstrumentation(data);} else {ii null;}final ContextImpl appContext ContextImpl.createAppContext(this, data.info);mConfigurationController.updateLocaleListFromAppContext(appContext);...// Continue loading instrumentation.if (ii ! null) {initInstrumentation(ii, data, appContext);} else {mInstrumentation new Instrumentation();mInstrumentation.basicInit(this);}...// Allow disk access during application and provider setup. This could// block processing ordered broadcasts, but later processing would// probably end up doing the same disk access.Application app;final StrictMode.ThreadPolicy savedPolicy StrictMode.allowThreadDiskWrites();final StrictMode.ThreadPolicy writesAllowedPolicy StrictMode.getThreadPolicy();try {// If the app is being launched for full backup or restore, bring it up in// a restricted environment with the base application class.app data.info.makeApplicationInner(data.restrictedBackupMode, null); // 1...// Do this after providers, since instrumentation tests generally start their// test thread at this point, and we dont want that racing.try {mInstrumentation.onCreate(data.instrumentationArgs);}catch (Exception e) {throw new RuntimeException(Exception thrown in onCreate() of data.instrumentationName : e.toString(), e);}try {mInstrumentation.callApplicationOnCreate(app); // 2} catch (Exception e) {if (!mInstrumentation.onException(app, e)) {throw new RuntimeException(Unable to create application app.getClass().getName() : e.toString(), e);}}} finally {// If the app targets O-MR1, or doesnt change the thread policy// during startup, clobber the policy to maintain behavior of b/36951662if (data.appInfo.targetSdkVersion Build.VERSION_CODES.O_MR1|| StrictMode.getThreadPolicy().equals(writesAllowedPolicy)) {StrictMode.setThreadPolicy(savedPolicy);}}
}2.7 makeApplication
首先来看app data.info.makeApplicationInner(data.restrictedBackupMode, null);
这里data是AppBindDatainfo是LoadedApk。
private Application makeApplicationInner(boolean forceDefaultAppClass,Instrumentation instrumentation, boolean allowDuplicateInstances) {if (mApplication ! null) {return mApplication;}try {final java.lang.ClassLoader cl getClassLoader();if (!mPackageName.equals(android)) {Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,initializeJavaContextClassLoader);initializeJavaContextClassLoader();Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);}// Rewrite the R constants for all library apks.SparseArrayString packageIdentifiers getAssets().getAssignedPackageIdentifiers(false, false);for (int i 0, n packageIdentifiers.size(); i n; i) {final int id packageIdentifiers.keyAt(i);if (id 0x01 || id 0x7f) {continue;}rewriteRValues(cl, packageIdentifiers.valueAt(i), id);}ContextImpl appContext ContextImpl.createAppContext(mActivityThread, this);// The network security config needs to be aware of multiple// applications in the same process to handle discrepanciesNetworkSecurityConfigProvider.handleNewApplication(appContext);app mActivityThread.mInstrumentation.newApplication(cl, appClass, appContext);appContext.setOuterContext(app);} catch (Exception e) {if (!mActivityThread.mInstrumentation.onException(app, e)) {Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);throw new RuntimeException(Unable to instantiate application appClass package mPackageName : e.toString(), e);}}mActivityThread.mAllApplications.add(app);mApplication app;if (!allowDuplicateInstances) {synchronized (sApplications) {sApplications.put(mPackageName, app);}}if (instrumentation ! null) {try {instrumentation.callApplicationOnCreate(app);} catch (Exception e) {if (!instrumentation.onException(app, e)) {Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);throw new RuntimeException(Unable to create application app.getClass().getName() : e.toString(), e);}}}Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);return app;
}这里首先拿到ClassLoader然后创建了appContext最后newApplication
app mActivityThread.mInstrumentation.newApplication(cl, appClass, appContext);public Application newApplication(ClassLoader cl, String className, Context context)throws InstantiationException, IllegalAccessException,
ClassNotFoundException {Application app getFactory(context.getPackageName()).instantiateApplication(cl, className);app.attach(context);return app;
}然后调用到了Application的attach
/* package */ final void attach(Context context) {attachBaseContext(context);mLoadedApk ContextImpl.getImpl(context).mPackageInfo;
}继续看makeApplicationInner#instrumentation.callApplicationOnCreate(app);
public void callApplicationOnCreate(Application app) {app.onCreate();
}这就调用到了Application的onCreate也就是我们经常继承Application的onCreate。
2.8 attachApplication
在ActivityManagerService#attachApplicationLocked中 bindApplication之后就进入到finishAttachApplicationInner。
private void finishAttachApplicationInner(long startSeq, int uid, int pid) {// See if the top visible activity is waiting to run in this process...if (normalMode) {try {didSomething mAtmInternal.attachApplication(app.getWindowProcessController());} catch (Exception e) {Slog.wtf(TAG, Exception thrown launching activities in app, e);badApp true;}}// Find any services that should be running in this process...if (!badApp) {try {didSomething | mServices.attachApplicationLocked(app, processName);checkTime(startTime, finishAttachApplicationInner: after mServices.attachApplicationLocked);} catch (Exception e) {Slog.wtf(TAG, Exception thrown starting services in app, e);badApp true;}}
}来看看mAtmInternal.attachApplication(app.getWindowProcessController());
HotPath(caller HotPath.PROCESS_CHANGE)
Override
public 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);}}
}调用到RootWindowContainer.attachApplication。
boolean attachApplication(WindowProcessController app) throws RemoteException {try {return mAttachApplicationHelper.process(app);} finally {mAttachApplicationHelper.reset();}
}boolean process(WindowProcessController app) throws RemoteException {mApp app;for (int displayNdx getChildCount() - 1; displayNdx 0; --displayNdx) {getChildAt(displayNdx).forAllRootTasks(this);if (mRemoteException ! null) {throw mRemoteException;}}if (!mHasActivityStarted) {ensureActivitiesVisible(null /* starting */, 0 /* configChanges */,false /* preserveWindows */);}return mHasActivityStarted;
}先来看getChildAt(displayNdx).forAllRootTasks(this);
// frameworks/base/services/core/java/com/android/server/wm/WindowContainer.java
boolean forAllRootTasks(PredicateTask callback) {return forAllRootTasks(callback, true /* traverseTopToBottom */);
}boolean forAllRootTasks(PredicateTask callback, boolean traverseTopToBottom) {int count mChildren.size();if (traverseTopToBottom) {for (int i count - 1; i 0; --i) {if (mChildren.get(i).forAllRootTasks(callback, traverseTopToBottom)) {return true;}}} else {for (int i 0; i count; i) {if (mChildren.get(i).forAllRootTasks(callback, traverseTopToBottom)) {return true;}// Root tasks may be removed from this display. Ensure each task will be processed// and the loop will end.int newCount mChildren.size();i - count - newCount;count newCount;}}return false;
}继续看Task#forAllRootTasks
// frameworks/base/services/core/java/com/android/server/wm/Task.java
Override
void forAllRootTasks(ConsumerTask callback, boolean traverseTopToBottom) {if (isRootTask()) {callback.accept(this);}
}这就回到了AttachApplicationHelper
// frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java
private class AttachApplicationHelper implements ConsumerTask, PredicateActivityRecord {Overridepublic void accept(Task rootTask) {if (mRemoteException ! null) {return;}if (rootTask.getVisibility(null /* starting */) TASK_FRAGMENT_VISIBILITY_INVISIBLE) {return;}mTop rootTask.topRunningActivity();rootTask.forAllActivities(this);}
}继续看
// frameworks/base/services/core/java/com/android/server/wm/WindowContainer.java
boolean forAllActivities(PredicateActivityRecord callback) {return forAllActivities(callback, true /*traverseTopToBottom*/);
}boolean forAllActivities(PredicateActivityRecord 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/ActivityRecord.java
Override
boolean forAllActivities(PredicateActivityRecord callback, boolean traverseTopToBottom) {return callback.test(this);
}最后是AttachApplicationHelper#test
// frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java
private class AttachApplicationHelper implements ConsumerTask, PredicateActivityRecord {Overridepublic boolean test(ActivityRecord r) {if (r.finishing || !r.showToCurrentUser() || !r.visibleIgnoringKeyguard|| r.app ! null || mApp.mUid ! r.info.applicationInfo.uid|| !mApp.mName.equals(r.processName)) {return false;}try {if (mTaskSupervisor.realStartActivityLocked(r, mApp,mTop r r.getTask().canBeResumed(r) /* andResume */,true /* checkConfig */)) {mHasActivityStarted true;}} catch (RemoteException e) {Slog.w(TAG, Exception in new application when starting activity mTop, e);mRemoteException e;return true;}return false;}
}2.9 StartActivity
//framework/base/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,boolean andResume, boolean checkConfig) throws RemoteException {// Have the window manager re-evaluate the orientation of the screen // based on the new activity order. Note that as a result of this,// it can call back into the activity manager with a new orientation. // We dont care about that, because the activity is// not currently running so we are just restarting it anyway.if (checkConfig) {// Deferring resume here because were going to launch new activity shortly.// We dont want to perform a redundant launch of the same // record while ensuring configurations and trying to resume // top activity of focused root task.mRootWindowContainer.ensureVisibilityAndConfig(r, r.getDisplayId(), false /* markFrozenIfConfigChanged */, true /* deferResume */);}// Create activity launch transaction.final ClientTransaction clientTransaction ClientTransaction.obtain(proc.getThread(), r.token);final boolean isTransitionForward r.isTransitionForward();final IBinder fragmentToken r.getTaskFragment().getFragmentToken();final int deviceId getDeviceIdForDisplayId(r.getDisplayId());clientTransaction.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(), deviceId,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,r.shouldSendCompatFakeFocus());} else {lifecycleItem PauseActivityItem.obtain();}clientTransaction.setLifecycleStateRequest(lifecycleItem);// Schedule transaction.mService.getLifecycleManager().scheduleTransaction(clientTransaction);
}这里checkConfig为true
//framework/base/services/core/java/com/android/server/wm/RootWindowContainer.java
/*** Ensure all activities visibility, update orientation and configuration.** param starting The currently starting activity or {code null} if there is none.* param displayId The id of the display where operation is executed.* param markFrozenIfConfigChanged Whether to set* {link ActivityRecord#frozenBeforeDestroy} to {code true} if config changed.* param deferResume Whether to defer resume while updating config.* return true if starting activity was kept or wasnt provided, * false if it was relaunched* because of configuration update.*/
boolean ensureVisibilityAndConfig(ActivityRecord starting, int displayId,boolean markFrozenIfConfigChanged, boolean deferResume) {// First ensure visibility without updating the config just yet. // We need this to know what activities are affecting configuration now.// Passing null here for starting param value, so that visibility of actual startingensureActivitiesVisible(null /* starting */, 0 /* configChanges */,false /* preserveWindows */, false /* notifyClients */);
}继续看mService.getLifecycleManager().scheduleTransaction(clientTransaction);
//framework/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)) {// If client is not an instance of Binder - its a remote call and at this point it is// safe to recycle the object. All objects used for local calls will be recycled after// the transaction is executed on client in ActivityThread.transaction.recycle();}
}//framework/base/core/java/android/app/servertransaction/ClientTransaction.java
public void schedule() throws RemoteException {mClient.scheduleTransaction(this);
}//framework/base/core/java/android/app/ActivityThread.java
private class ApplicationThread extends IApplicationThread.Stub {Overridepublic void scheduleTransaction(ClientTransaction transaction) throws RemoteException {ActivityThread.this.scheduleTransaction(transaction);}
}//framework/base/core/java/android/app/ClientTransactionHandler.java
/** Prepare and schedule transaction for execution. */
void scheduleTransaction(ClientTransaction transaction) {transaction.preExecute(this);sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}case EXECUTE_TRANSACTION:
final ClientTransaction transaction (ClientTransaction) msg.obj;
mTransactionExecutor.execute(transaction);
if (isSystem()) {// Client transactions inside system process are recycled on the client side// instead of ClientLifecycleManager to avoid being cleared before this// message is handled.transaction.recycle();
}
// TODO(lifecycler): Recycle locally scheduled transactions.
break;//framework/base/core/java/android/app/servertransaction/TransactionExecutor.java
public void executeCallbacks(ClientTransaction transaction) {for (int i 0; i size; i) {final ClientTransactionItem item callbacks.get(i);item.execute(mTransactionHandler, token, mPendingActions);item.postExecute(mTransactionHandler, token, mPendingActions);}
}这里执行的是ClientTransactionItem#execute
public abstract class ClientTransactionItem implements BaseClientRequest, Parcelable这里ClientTransactionItem是一个抽象类结合我们上面传入的是LaunchActivityItem所以这里item就是LaunchActivityItem。
//framework/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);ActivityClientRecord r new ActivityClientRecord(token, mIntent, mIdent, mInfo,mOverrideConfig, mReferrer, mVoiceInteractor, mState, mPersistentState,mPendingResults, mPendingNewIntents, mActivityOptions, mIsForward, mProfilerInfo,client, mAssistToken, mShareableActivityToken, mLaunchedFromBubble,mTaskFragmentToken);client.handleLaunchActivity(r, pendingActions, mDeviceId, null /* customIntent */);Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);}
}这里很清晰了执行的是client.handleLaunchActivity
//framework/base/core/java/android/app/ActivityThread.java
Override
public Activity handleLaunchActivity(ActivityClientRecord r,PendingTransactionActions pendingActions,int deviceId, Intent customIntent) {final Activity a performLaunchActivity(r, customIntent);
}private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {ContextImpl appContext createBaseContextForActivity(r);Activity activity null;try {java.lang.ClassLoader cl appContext.getClassLoader();activity 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);}} Application app r.packageInfo.makeApplicationInner(false, mInstrumentation);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,r.activityConfigCallback,r.assistToken, r.shareableActivityToken);r.activity activity;if (r.isPersistable()) {mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);} else {mInstrumentation.callActivityOnCreate(activity, r.state);}
}performLaunchActivity首先调用mInstrumentation的newActivity创建一个Activity。
public Activity newActivity(ClassLoader cl, String className, Intent intent)throws InstantiationException, IllegalAccessException, ClassNotFoundException {String pkg intent ! null intent.getComponent() ! null? intent.getComponent().getPackageName() : null;return getFactory(pkg).instantiateActivity(cl, className, intent);
}getFactory(pkg)拿到的是一个AppComponentFactory
public NonNull Activity instantiateActivity(NonNull ClassLoader cl, NonNull String className, Nullable Intent intent)throws InstantiationException, IllegalAccessException, ClassNotFoundException {return (Activity) cl.loadClass(className).newInstance();
}Activity创建之后调用Application app r.packageInfo.makeApplicationInner(false, mInstrumentation);
由于前面Application 已经创建了所以这里直接返回已经创建的Application。
2.10 Activity Create
继续看activity.attach。
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, r.activityConfigCallback,r.assistToken, r.shareableActivityToken);//framework/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) {attachBaseContext(context);mWindow new PhoneWindow(this, window, activityConfigCallback);mUiThread Thread.currentThread();mMainThread aThread;mWindow.setWindowManager((WindowManager)context.getSystemService(Context.WINDOW_SERVICE),mToken, mComponent.flattenToString(),(info.flags ActivityInfo.FLAG_HARDWARE_ACCELERATED) ! 0);
}最后调用callActivityOnCreate。
//framework/base/core/java/android/app/Instrumentation.java
public void callActivityOnCreate(Activity activity, Bundle icicle) {prePerformCreate(activity);activity.performCreate(icicle);postPerformCreate(activity);
}//framework/base/core/java/android/app/Activity.java
final void performCreate(Bundle icicle) {performCreate(icicle, null);
}UnsupportedAppUsage(maxTargetSdk Build.VERSION_CODES.R, trackingBug 170729553)
final void performCreate(Bundle icicle, PersistableBundle persistentState) {if (persistentState ! null) {onCreate(icicle, persistentState);} else {onCreate(icicle);}
}至此调用到了Activity的onCreate。
2.11 Activity Resume
回到ActivityTaskSupervisor#realStartActivityLocked再activity创建设为地方也传入了ResumeActivityItem。
//framework/base/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
if (andResume) {lifecycleItem ResumeActivityItem.obtain(isTransitionForward,r.shouldSendCompatFakeFocus());
} else {lifecycleItem PauseActivityItem.obtain();
}//framework/base/core/java/android/app/servertransaction/TransactionExecutor.java
public void execute(ClientTransaction transaction) {executeCallbacks(transaction);executeLifecycleState(transaction);
}
public void executeCallbacks(ClientTransaction transaction) {for (int i 0; i size; i) {final ClientTransactionItem item callbacks.get(i);item.execute(mTransactionHandler, token, mPendingActions);item.postExecute(mTransactionHandler, token, mPendingActions);}
}
/** Transition to the final state if requested by the transaction. */
private void executeLifecycleState(ClientTransaction transaction) {final ActivityLifecycleItem lifecycleItem transaction.getLifecycleStateRequest();// Execute the final transition with proper parameters.lifecycleItem.execute(mTransactionHandler, token, mPendingActions);lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
}执行完ClientTransaction之后会执行ActivityLifecycleItem。
这里就执行ResumeActivityItem的execute、
//framework/base/core/java/android/app/servertransaction/ResumeActivityItem.java
Override
public void execute(ClientTransactionHandler client, ActivityClientRecord r,PendingTransactionActions pendingActions) {Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, activityResume);client.handleResumeActivity(r, true /* finalStateRequest */, mIsForward,mShouldSendCompatFakeFocus, RESUME_ACTIVITY);Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}//framework/base/core/java/android/app/ActivityThread.java
Override
public void handleResumeActivity(ActivityClientRecord r, boolean finalStateRequest,boolean isForward, boolean shouldSendCompatFakeFocus, String reason) {if (!performResumeActivity(r, finalStateRequest, reason)) {return;}if (r.window null !a.mFinished willBeVisible) {if (a.mVisibleFromClient) {if (!a.mWindowAdded) {a.mWindowAdded true;wm.addView(decor, l);}}}if (!r.activity.mFinished willBeVisible r.activity.mDecor ! null !r.hideForNow) {if (r.activity.mVisibleFromClient) {r.activity.makeVisible();}}mNewActivities.add(r);if (localLOGV) Slog.v(TAG, Scheduling idle handler for r);Looper.myQueue().addIdleHandler(new Idler());
}public boolean performResumeActivity(ActivityClientRecord r, boolean finalStateRequest, String reason) {r.activity.performResume(r.startsNotResumed, reason);
}final void performResume(boolean followedByPause, String reason) {// mResumed is set by the instrumentationmInstrumentation.callActivityOnResume(this);
}public void callActivityOnResume(Activity activity) {activity.mResumed true;activity.onResume();if (mActivityMonitors ! null) {synchronized (mSync) {final int N mActivityMonitors.size();for (int i0; iN; i) {final ActivityMonitor am mActivityMonitors.get(i);am.match(activity, activity, activity.getIntent());}}}
}这调用activity的onResume()。
3 流程图 本文完。