欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 教育 > 培训 > Android activity 启动流程

Android activity 启动流程

2024/10/24 5:20:08 来源:https://blog.csdn.net/qq_23025319/article/details/142987037  浏览:    关键词:Android activity 启动流程

Android activity 启动流程

本文主要记录下acitivty的启动流程.

1: Activity

我们都知道启动activity调用方法:

startActivity(Intent intent)startActivity(Intent intent, @Nullable Bundle options)startActivityForResult(@RequiresPermission Intent intent, int requestCode)startActivityForResult(@RequiresPermission Intent intent, int requestCode,@Nullable Bundle options)

首先我们先跟踪下代码

  1. context.startActivity(new Intent(context, TestActivity.class));
  2. this.startActivity(intent, null);
  3. startActivityForResult(intent, -1);
  4. startActivityForResult(intent, requestCode, null);

我们可以看下startActivityForResult(intent, requestCode, null)的代码.

public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,@Nullable Bundle options) {if (mParent == null) {options = transferSpringboardActivityOptions(options);Instrumentation.ActivityResult ar =mInstrumentation.execStartActivity(this, mMainThread.getApplicationThread(), mToken, this,intent, requestCode, options);if (ar != null) {mMainThread.sendActivityResult(mToken, mEmbeddedID, requestCode, ar.getResultCode(),ar.getResultData());}if (requestCode >= 0) {// If this start is requesting a result, we can avoid making// the activity visible until the result is received.  Setting// this code during onCreate(Bundle savedInstanceState) or onResume() will keep the// activity hidden during this time, to avoid flickering.// This can only be done when a result is requested because// that guarantees we will get information back when the// activity is finished, no matter what happens to it.mStartedActivity = true;}cancelInputsAndStartExitTransition(options);// TODO Consider clearing/flushing other event sources and events for child windows.} else {if (options != null) {mParent.startActivityFromChild(this, intent, requestCode, options);} else {// Note we want to go through this method for compatibility with// existing applications that may have overridden it.mParent.startActivityFromChild(this, intent, requestCode);}}
}

可以看到最终调用了 Instrumentation 的 execStartActivity.

2: Instrumentation

源码可参考:https://www.androidos.net.cn/android/10.0.0_r6/xref/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) {IApplicationThread whoThread = (IApplicationThread) contextThread;Uri referrer = target != null ? target.onProvideReferrer() : null;if (referrer != null) {intent.putExtra(Intent.EXTRA_REFERRER, referrer);}if (mActivityMonitors != null) {synchronized (mSync) {final int N = mActivityMonitors.size();for (int i=0; i<N; i++) {final ActivityMonitor am = mActivityMonitors.get(i);ActivityResult result = null;if (am.ignoreMatchingSpecificIntents()) {result = am.onStartActivity(intent);}if (result != null) {am.mHits++;return result;} else if (am.match(who, null, intent)) {am.mHits++;if (am.isBlocking()) {return requestCode >= 0 ? am.getResult() : null;}break;}}}}try {intent.migrateExtraStreamToClipData();intent.prepareToLeaveProcess(who);int result = ActivityTaskManager.getService().startActivity(whoThread, who.getBasePackageName(), intent,intent.resolveTypeIfNeeded(who.getContentResolver()),token, target != null ? target.mEmbeddedID : null,requestCode, 0, null, options);checkStartActivityResult(result, intent);} catch (RemoteException e) {throw new RuntimeException("Failure from system", e);}return null;}

可以看到 最终调用 :ActivityTaskManager.getService().startActivity.

3: ActivityTaskManager

源码可参考: https://www.androidos.net.cn/android/10.0.0_r6/xref/frameworks/base/core/java/android/app/ActivityTaskManager.java

首先看下getService方法:

 public static IActivityTaskManager getService() {return IActivityTaskManagerSingleton.get();}

可以看到返回的是一个类型为IActivityTaskManager的对象.

下面是IActivityTaskManagerSingleton的代码:

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

4: IActivityTaskManager.aidl

源码参考:https://www.androidos.net.cn/android/10.0.0_r6/xref/frameworks/base/core/java/android/app/IActivityTaskManager.aidl

interface IActivityTaskManager {int startActivity(in IApplicationThread caller, in String callingPackage, in Intent intent,in String resolvedType, in IBinder resultTo, in String resultWho, int requestCode,int flags, in ProfilerInfo profilerInfo, in Bundle options);...   
}

我们可以根据aidl来搜索继承IActivityTaskManager.Stub ,从而找到ActivityTaskManagerService.

5: ActivityTaskManagerService

源码参考: https://www.androidos.net.cn/android/10.0.0_r6/xref/frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java

我们看下startActivity的调用链路:

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

startActivityAsUser(… UserHandle.getCallingUserId())

 @Overridepublic int startActivityAsUser(IApplicationThread caller, String callingPackage,Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,true /*validateIncomingUser*/);}

startActivityAsUser(… ,UserHandle.getCallingUserId(), true)

 int startActivityAsUser(IApplicationThread caller, String callingPackage,Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId,boolean validateIncomingUser) {enforceNotIsolatedCaller("startActivityAsUser");userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");// TODO: Switch to user app stacks here.return getActivityStartController().obtainStarter(intent, "startActivityAsUser").setCaller(caller).setCallingPackage(callingPackage).setResolvedType(resolvedType).setResultTo(resultTo).setResultWho(resultWho).setRequestCode(requestCode).setStartFlags(startFlags).setProfilerInfo(profilerInfo).setActivityOptions(bOptions).setMayWait(userId).execute();}

根据getActivityStartController()

  ActivityStartController getActivityStartController() {return mActivityStartController;}

根据ActivityStartController的obtainStarter()返回ActivityStarter.

/*** @return A starter to configure and execute starting an activity. It is valid until after*         {@link ActivityStarter#execute} is invoked. At that point, the starter should be*         considered invalid and no longer modified or used.*/ActivityStarter obtainStarter(Intent intent, String reason) {return mFactory.obtain().setIntent(intent).setReason(reason);}

6: ActivityStarter

 int execute() {try {// TODO(b/64750076): Look into passing request directly to these methods to allow// for transactional diffs and preprocessing.if (mRequest.mayWait) {return startActivityMayWait(mRequest.caller, mRequest.callingUid,mRequest.callingPackage, mRequest.realCallingPid, mRequest.realCallingUid,mRequest.intent, mRequest.resolvedType,mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,mRequest.resultWho, mRequest.requestCode, mRequest.startFlags,mRequest.profilerInfo, mRequest.waitResult, mRequest.globalConfig,mRequest.activityOptions, mRequest.ignoreTargetSecurity, mRequest.userId,mRequest.inTask, mRequest.reason,mRequest.allowPendingRemoteAnimationRegistryLookup,mRequest.originatingPendingIntent, mRequest.allowBackgroundActivityStart);} else {return startActivity(mRequest.caller, mRequest.intent, mRequest.ephemeralIntent,mRequest.resolvedType, mRequest.activityInfo, mRequest.resolveInfo,mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,mRequest.resultWho, mRequest.requestCode, mRequest.callingPid,mRequest.callingUid, mRequest.callingPackage, mRequest.realCallingPid,mRequest.realCallingUid, mRequest.startFlags, mRequest.activityOptions,mRequest.ignoreTargetSecurity, mRequest.componentSpecified,mRequest.outActivity, mRequest.inTask, mRequest.reason,mRequest.allowPendingRemoteAnimationRegistryLookup,mRequest.originatingPendingIntent, mRequest.allowBackgroundActivityStart);}} finally {onExecutionComplete();}}

查看startActivity方法:

private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,String callingPackage, int realCallingPid, int realCallingUid, int startFlags,SafeActivityOptions options,boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity,TaskRecord inTask, boolean allowPendingRemoteAnimationRegistryLookup,PendingIntentRecord originatingPendingIntent, boolean allowBackgroundActivityStart) {mSupervisor.getActivityMetricsLogger().notifyActivityLaunching(intent);...ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(),resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null,mSupervisor, checkedOptions, sourceRecord);if (outActivity != null) {outActivity[0] = r;}...mService.onStartActivitySetDidAppSwitch();mController.doPendingActivityLaunches(false);final int res = startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags,true /* doResume */, checkedOptions, inTask, outActivity, restrictedBgActivity);mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(res, outActivity[0]);return res;
}

创建ActivityRecord对象. 调用startActivity()并return, 我们看下另一个startActivity方法, 代码如下:

private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,ActivityRecord[] outActivity, boolean restrictedBgActivity) {int result = START_CANCELED;final ActivityStack startedActivityStack;try {mService.mWindowManager.deferSurfaceLayout();result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,startFlags, doResume, options, inTask, outActivity, restrictedBgActivity);} finally {final ActivityStack currentStack = r.getActivityStack();startedActivityStack = currentStack != null ? currentStack : mTargetStack;if (ActivityManager.isStartResultSuccessful(result)) {if (startedActivityStack != null) {// If there is no state change (e.g. a resumed activity is reparented to// top of another display) to trigger a visibility/configuration checking,// we have to update the configuration for changing to different display.final ActivityRecord currentTop =startedActivityStack.topRunningActivityLocked();if (currentTop != null && currentTop.shouldUpdateConfigForDisplayChanged()) {mRootActivityContainer.ensureVisibilityAndConfig(currentTop, currentTop.getDisplayId(),true /* markFrozenIfConfigChanged */, false /* deferResume */);}}} else {// If we are not able to proceed, disassociate the activity from the task.// Leaving an activity in an incomplete state can lead to issues, such as// performing operations without a window container.final ActivityStack stack = mStartActivity.getActivityStack();if (stack != null) {stack.finishActivityLocked(mStartActivity, RESULT_CANCELED,null /* intentResultData */, "startActivity", true /* oomAdj */);}// Stack should also be detached from display and be removed if it's empty.if (startedActivityStack != null && startedActivityStack.isAttached()&& startedActivityStack.numActivities() == 0&& !startedActivityStack.isActivityTypeHome()) {startedActivityStack.remove();}}mService.mWindowManager.continueSurfaceLayout();}postStartActivityProcessing(r, result, startedActivityStack);return result;}

查看startActivityUnchecked方法.

// Note: This method should only be called from {@link startActivity}.
private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,ActivityRecord[] outActivity, boolean restrictedBgActivity) {// 初始化mInTask:TaskRecord 记录Task的信息, setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,voiceInteractor, restrictedBgActivity);......//    mTargetStack: ActivityStack栈信息.mTargetStack.startActivityLocked(mStartActivity, topFocused, newTask, mKeepCurTransition,mOptions);if (mDoResume) {final ActivityRecord topTaskActivity =mStartActivity.getTaskRecord().topRunningActivityLocked();if (!mTargetStack.isFocusable()|| (topTaskActivity != null && topTaskActivity.mTaskOverlay&& mStartActivity != topTaskActivity)) {// If the activity is not focusable, we can't resume it, but still would like to// make sure it becomes visible as it starts (this will also trigger entry// animation). An example of this are PIP activities.// Also, we don't want to resume activities in a task that currently has an overlay// as the starting activity just needs to be in the visible paused state until the// over is removed.mTargetStack.ensureActivitiesVisibleLocked(mStartActivity, 0, !PRESERVE_WINDOWS);// Go ahead and tell window manager to execute app transition for this activity// since the app transition will not be triggered through the resume channel.mTargetStack.getDisplay().mDisplayContent.executeAppTransition();} else {// If the target stack was not previously focusable (previous top running activity// on that stack was not visible) then any prior calls to move the stack to the// will not update the focused stack.  If starting the new activity now allows the// task stack to be focusable, then ensure that we now update the focused stack// accordingly.if (mTargetStack.isFocusable()&& !mRootActivityContainer.isTopDisplayFocusedStack(mTargetStack)) {mTargetStack.moveToFront("startActivityUnchecked");}mRootActivityContainer.resumeFocusedStacksTopActivities(mTargetStack, mStartActivity, mOptions);}} else if (mStartActivity != null) {mSupervisor.mRecentTasks.add(mStartActivity.getTaskRecord());}mRootActivityContainer.updateUserStack(mStartActivity.mUserId, mTargetStack);mSupervisor.handleNonResizableTaskIfNeeded(mStartActivity.getTaskRecord(),preferredWindowingMode, mPreferredDisplayId, mTargetStack);return START_SUCCESS;
}

mTargetStack: ActivityStack栈信息.

TaskRecord: 记录Task的信息.

mRootActivityContainer: RootActivityContainer

mSupervisor: ActivityStackSupervisor

7: RootActivityContainer

代码参考: https://www.androidos.net.cn/android/10.0.0_r6/xref/frameworks/base/services/core/java/com/android/server/wm/RootActivityContainer.java

mRootActivityContainer.resumeFocusedStacksTopActivities(mTargetStack, mStartActivity, mOptions);

   boolean resumeFocusedStacksTopActivities() {return resumeFocusedStacksTopActivities(null, null, null);}boolean resumeFocusedStacksTopActivities(ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {if (!mStackSupervisor.readyToResume()) {return false;}boolean result = false;if (targetStack != null && (targetStack.isTopStackOnDisplay()|| getTopDisplayFocusedStack() == targetStack)) {result = targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);}for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {boolean resumedOnDisplay = false;final ActivityDisplay display = mActivityDisplays.get(displayNdx);for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {final ActivityStack stack = display.getChildAt(stackNdx);final ActivityRecord topRunningActivity = stack.topRunningActivityLocked();if (!stack.isFocusableAndVisible() || topRunningActivity == null) {continue;}if (stack == targetStack) {// Simply update the result for targetStack because the targetStack had// already resumed in above. We don't want to resume it again, especially in// some cases, it would cause a second launch failure if app process was dead.resumedOnDisplay |= result;continue;}if (display.isTopStack(stack) && topRunningActivity.isState(RESUMED)) {// Kick off any lingering app transitions form the MoveTaskToFront operation,// but only consider the top task and stack on that display.stack.executeAppTransition(targetOptions);} else {resumedOnDisplay |= topRunningActivity.makeActiveIfNeeded(target);}}if (!resumedOnDisplay) {// In cases when there are no valid activities (e.g. device just booted or launcher// crashed) it's possible that nothing was resumed on a display. Requesting resume// of top activity in focused stack explicitly will make sure that at least home// activity is started and resumed, and no recursion occurs.final ActivityStack focusedStack = display.getFocusedStack();if (focusedStack != null) {focusedStack.resumeTopActivityUncheckedLocked(target, targetOptions);}}}return result;}

接着我们再看下resumeTopActivityUncheckedLocked方法

8: ActivityStack

代码参考: https://www.androidos.net.cn/android/10.0.0_r6/xref/frameworks/base/services/core/java/com/android/server/wm/ActivityStack.java

 @GuardedBy("mService")boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {if (mInResumeTopActivity) {// Don't even start recursing.return false;}boolean result = false;try {// Protect against recursion.mInResumeTopActivity = true;result = resumeTopActivityInnerLocked(prev, options);// When resuming the top activity, it may be necessary to pause the top activity (for// example, returning to the lock screen. We suppress the normal pause logic in// {@link #resumeTopActivityUncheckedLocked}, since the top activity is resumed at the// end. We call the {@link ActivityStackSupervisor#checkReadyForSleepLocked} again here// to ensure any necessary pause logic occurs. In the case where the Activity will be// shown regardless of the lock screen, the call to// {@link ActivityStackSupervisor#checkReadyForSleepLocked} is skipped.final ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */);if (next == null || !next.canTurnScreenOn()) {checkReadyForSleep();}} finally {mInResumeTopActivity = false;}return result;}

resumeTopActivityInnerLocked方法:

	 @GuardedBy("mService")private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {if (!mService.isBooting() && !mService.isBooted()) {// Not ready yet!return false;}// Find the next top-most activity to resume in this stack that is not finishing and is// focusable. If it is not focusable, we will fall into the case below to resume the// top activity in the next focusable task.ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */);......if (next.attachedToProcess()) {if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Resume running: " + next+ " stopped=" + next.stopped + " visible=" + next.visible);......}else {// Whoops, need to restart this activity!if (!next.hasBeenLaunched) {next.hasBeenLaunched = true;} else {if (SHOW_APP_STARTING_PREVIEW) {next.showStartingWindow(null /* prev */, false /* newTask */,false /* taskSwich */);}if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Restarting: " + next);}if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Restarting " + next);mStackSupervisor.startSpecificActivityLocked(next, true, true);}return true;}

next.attachedToProcess(): true已经附加到进程,恢复页面并更新栈; 否则就需要 (重新) 启动目标 Activity.

此时我们看到调用的是:mStackSupervisor.startSpecificActivityLocked方法.

9: ActivityStackSupervisor

参考代码: https://www.androidos.net.cn/android/10.0.0_r6/xref/frameworks/base/services/core/java/com/android/server/wm/ActivityStackSupervisor.java

startSpecificActivityLocked方法如下:

   void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) {// Is this activity's application already running?final WindowProcessController wpc =mService.getProcessController(r.processName, r.info.applicationInfo.uid);boolean knownToBeDead = false;if (wpc != null && wpc.hasThread()) {try {realStartActivityLocked(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;}// Suppress transition until the new activity becomes ready, otherwise the keyguard can// appear for a short amount of time before the new process with the new activity had the// ability to set its showWhenLocked flags.if (getKeyguardController().isKeyguardLocked()) {r.notifyUnknownVisibilityLaunched();}try {if (Trace.isTagEnabled(TRACE_TAG_ACTIVITY_MANAGER)) {Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "dispatchingStartProcess:"+ r.processName);}// Post message to start process to avoid possible deadlock of calling into AMS with the// ATMS lock held.final Message msg = PooledLambda.obtainMessage(ActivityManagerInternal::startProcess, mService.mAmInternal, r.processName,r.info.applicationInfo, knownToBeDead, "activity", r.intent.getComponent());mService.mH.sendMessage(msg);} finally {Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);}}

可以看到先根据processName和uid判断应用进程是否存在, 如果存在调用realStartActivityLocked.

否则mService.mH.sendMessage(msg);

10 :ActivityManagerInternal

代码参考: https://www.androidos.net.cn/android/10.0.0_r6/xref/frameworks/base/core/java/android/app/ActivityManagerInternal.java

startProcess方法如下:

/** Starts a given process. */public abstract void startProcess(String processName, ApplicationInfo info,boolean knownToBeDead, String hostingType, ComponentName hostingName);

11: ActivityManagerService

ActivityManagerInternal实现者是AMS,

代码参考: https://www.androidos.net.cn/android/10.0.0_r6/xref/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

 @Overridepublic void startProcess(String processName, ApplicationInfo info,boolean knownToBeDead, String hostingType, ComponentName hostingName) {try {if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "startProcess:"+ processName);}synchronized (ActivityManagerService.this) {startProcessLocked(processName, info, knownToBeDead, 0 /* intentFlags */,new HostingRecord(hostingType, hostingName),false /* allowWhileBooting */, false /* isolated */,true /* keepIfLarge */);}} finally {Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);}}

查看startProcessLocked:

  @GuardedBy("this")final ProcessRecord startProcessLocked(String processName,ApplicationInfo info, boolean knownToBeDead, int intentFlags,HostingRecord hostingRecord, boolean allowWhileBooting,boolean isolated, boolean keepIfLarge) {return mProcessList.startProcessLocked(processName, info, knownToBeDead, intentFlags,hostingRecord, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,null /* crashHandler */);}

12: ProcessList

代码参考: https://www.androidos.net.cn/android/10.0.0_r6/xref/frameworks/base/services/core/java/com/android/server/am/ProcessList.java

startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,boolean disableHiddenApiChecks, boolean mountExtStorageFull,String abiOverride) 如下:

  @GuardedBy("mService")boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,boolean disableHiddenApiChecks, boolean mountExtStorageFull,String abiOverride) {if (app.pendingStart) {return true;}......return startProcessLocked(hostingRecord, entryPoint, app, uid, gids,runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet, invokeWith,startTime);...}

看下最终的startProcessLocked方法:

 @GuardedBy("mService")
boolean startProcessLocked(HostingRecord hostingRecord,String entryPoint,ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,String seInfo, String requiredAbi, String instructionSet, String invokeWith,long startTime) {app.pendingStart = true;app.killedByAm = false;app.removed = false;app.killed = false;if (app.startSeq != 0) {Slog.wtf(TAG, "startProcessLocked processName:" + app.processName+ " with non-zero startSeq:" + app.startSeq);}if (app.pid != 0) {Slog.wtf(TAG, "startProcessLocked processName:" + app.processName+ " with non-zero pid:" + app.pid);}final long startSeq = app.startSeq = ++mProcStartSeqCounter;app.setStartParams(uid, hostingRecord, seInfo, startTime);app.setUsingWrapper(invokeWith != null|| SystemProperties.get("wrap." + app.processName) != null);mPendingStarts.put(startSeq, app);if (mService.mConstants.FLAG_PROCESS_START_ASYNC) {if (DEBUG_PROCESSES) Slog.i(TAG_PROCESSES,"Posting procStart msg for " + app.toShortString());mService.mProcStartHandler.post(() -> {try {final Process.ProcessStartResult startResult = startProcess(app.hostingRecord,entryPoint, app, app.startUid, gids, runtimeFlags, mountExternal,app.seInfo, requiredAbi, instructionSet, invokeWith, app.startTime);synchronized (mService) {handleProcessStartedLocked(app, startResult, startSeq);}} catch (RuntimeException e) {synchronized (mService) {Slog.e(ActivityManagerService.TAG, "Failure starting process "+ app.processName, e);mPendingStarts.remove(startSeq);app.pendingStart = false;mService.forceStopPackageLocked(app.info.packageName,UserHandle.getAppId(app.uid),false, false, true, false, false, app.userId, "start failure");}}});return true;} else {try {final Process.ProcessStartResult startResult = startProcess(hostingRecord,entryPoint, app,uid, gids, runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet,invokeWith, startTime);handleProcessStartedLocked(app, startResult.pid, startResult.usingWrapper,startSeq, false);} catch (RuntimeException e) {Slog.e(ActivityManagerService.TAG, "Failure starting process "+ app.processName, e);app.pendingStart = false;mService.forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid),false, false, true, false, false, app.userId, "start failure");}return app.pid > 0;}}

查看startProcess方法:

 private Process.ProcessStartResult startProcess(HostingRecord hostingRecord, String entryPoint,ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,String seInfo, String requiredAbi, String instructionSet, String invokeWith,long startTime) {try {Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +app.processName);checkSlow(startTime, "startProcess: asking zygote to start proc");final Process.ProcessStartResult startResult;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,new String[] {PROC_START_SEQ_IDENT + app.startSeq});} else if (hostingRecord.usesAppZygote()) {final AppZygote appZygote = createAppZygoteForProcessIfNeeded(app);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,/*useUsapPool=*/ false,new String[] {PROC_START_SEQ_IDENT + app.startSeq});} else {startResult = Process.start(entryPoint,app.processName, uid, uid, gids, runtimeFlags, mountExternal,app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,app.info.dataDir, invokeWith, app.info.packageName,new String[] {PROC_START_SEQ_IDENT + app.startSeq});}checkSlow(startTime, "startProcess: returned from zygote!");return startResult;} finally {Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);}}

可以看到分为三种情况:

  1. usesWebviewZygote时调用startWebView
  2. usesAppZygote时创建appZygote,调用appZygote.getProcess().start
  3. 否则直接调用Process.start

我们看下Process类

13: Process

代码参考:https://www.androidos.net.cn/android/10.0.0_r6/xref/frameworks/base/core/java/android/os/Process.java

   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,@Nullable String[] zygoteArgs) {return ZYGOTE_PROCESS.start(processClass, niceName, uid, gid, gids,runtimeFlags, mountExternal, targetSdkVersion, seInfo,abi, instructionSet, appDataDir, invokeWith, packageName,/*useUsapPool=*/ true, zygoteArgs);}

其中ZYGOTE_PROCESS就是ZygoteProcess.

 /*** State associated with the zygote process.* @hide*/public static final ZygoteProcess ZYGOTE_PROCESS = new ZygoteProcess();

14: ZygoteProcess

代码参考: https://www.androidos.net.cn/android/10.0.0_r6/xref/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,boolean useUsapPool,@Nullable String[] zygoteArgs) {// TODO (chriswailes): Is there a better place to check this value?if (fetchUsapPoolEnabledPropWithMinInterval()) {informZygotesOfUsapPoolStatus();}try {return startViaZygote(processClass, niceName, uid, gid, gids,runtimeFlags, mountExternal, targetSdkVersion, seInfo,abi, instructionSet, appDataDir, invokeWith, /*startChildZygote=*/ false,packageName, useUsapPool, zygoteArgs);} catch (ZygoteStartFailedEx ex) {Log.e(LOG_TAG,"Starting VM process through Zygote failed");throw new RuntimeException("Starting VM process through Zygote failed", ex);}}

startViaZygote:

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,boolean useUsapPool,@Nullable String[] extraArgs)throws ZygoteStartFailedEx {ArrayList<String> argsForZygote = new ArrayList<>();// --runtime-args, --setuid=, --setgid=,// and --setgroups= must go firstargsForZygote.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_READ) {argsForZygote.add("--mount-external-read");} else if (mountExternal == Zygote.MOUNT_EXTERNAL_WRITE) {argsForZygote.add("--mount-external-write");} else if (mountExternal == Zygote.MOUNT_EXTERNAL_FULL) {argsForZygote.add("--mount-external-full");} else if (mountExternal == Zygote.MOUNT_EXTERNAL_INSTALLER) {argsForZygote.add("--mount-external-installer");} else if (mountExternal == Zygote.MOUNT_EXTERNAL_LEGACY) {argsForZygote.add("--mount-external-legacy");}argsForZygote.add("--target-sdk-version=" + targetSdkVersion);// --setgroups is a comma-separated listif (gids != null && gids.length > 0) {StringBuilder sb = new StringBuilder();sb.append("--setgroups=");int sz = gids.length;for (int i = 0; i < sz; i++) {if (i != 0) {sb.append(',');}sb.append(gids[i]);}argsForZygote.add(sb.toString());}if (niceName != null) {argsForZygote.add("--nice-name=" + niceName);}if (seInfo != null) {argsForZygote.add("--seinfo=" + seInfo);}if (instructionSet != null) {argsForZygote.add("--instruction-set=" + instructionSet);}if (appDataDir != null) {argsForZygote.add("--app-data-dir=" + appDataDir);}if (invokeWith != null) {argsForZygote.add("--invoke-with");argsForZygote.add(invokeWith);}if (startChildZygote) {argsForZygote.add("--start-child-zygote");}if (packageName != null) {argsForZygote.add("--package-name=" + packageName);}argsForZygote.add(processClass);if (extraArgs != null) {Collections.addAll(argsForZygote, extraArgs);}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),useUsapPool,argsForZygote);}}

继续查看zygoteSendArgsAndGetResult:

@GuardedBy("mLock")private Process.ProcessStartResult zygoteSendArgsAndGetResult(ZygoteState zygoteState, boolean useUsapPool, @NonNull ArrayList<String> args)throws ZygoteStartFailedEx {// Throw early if any of the arguments are malformed. This means we can// avoid writing a partial response to the zygote.for (String arg : args) {// Making two indexOf calls here is faster than running a manually fused loop due// to the fact that indexOf is a optimized intrinsic.if (arg.indexOf('\n') >= 0) {throw new ZygoteStartFailedEx("Embedded newlines not allowed");} else if (arg.indexOf('\r') >= 0) {throw new ZygoteStartFailedEx("Embedded carriage returns not allowed");}}/** See com.android.internal.os.ZygoteArguments.parseArgs()* Presently the wire format to the zygote process is:* a) a count of arguments (argc, in essence)* b) a number of newline-separated argument strings equal to count** After the zygote process reads these it will write the pid of* the child or -1 on failure, followed by boolean to* indicate whether a wrapper process was used.*/String msgStr = args.size() + "\n" + String.join("\n", args) + "\n";if (useUsapPool && mUsapPoolEnabled && canAttemptUsap(args)) {try {return attemptUsapSendArgsAndGetResult(zygoteState, msgStr);} catch (IOException ex) {// If there was an IOException using the USAP pool we will log the error and// attempt to start the process through the Zygote.Log.e(LOG_TAG, "IO Exception while communicating with USAP pool - "+ ex.getMessage());}}return attemptZygoteSendArgsAndGetResult(zygoteState, msgStr);}

attemptUsapSendArgsAndGetResult:

private Process.ProcessStartResult attemptUsapSendArgsAndGetResult(ZygoteState zygoteState, String msgStr)throws ZygoteStartFailedEx, IOException {try (LocalSocket usapSessionSocket = zygoteState.getUsapSessionSocket()) {final BufferedWriter usapWriter =new BufferedWriter(new OutputStreamWriter(usapSessionSocket.getOutputStream()),Zygote.SOCKET_BUFFER_SIZE);final DataInputStream usapReader =new DataInputStream(usapSessionSocket.getInputStream());usapWriter.write(msgStr);usapWriter.flush();Process.ProcessStartResult result = new Process.ProcessStartResult();result.pid = usapReader.readInt();// USAPs can't be used to spawn processes that need wrappers.result.usingWrapper = false;if (result.pid >= 0) {return result;} else {throw new ZygoteStartFailedEx("USAP specialization failed");}}}

可以看到zygoteState.getUsapSessionSocket 获取到Socket, 而是ZygoteState是 ZygoteProcess的内部类.

openZygoteSocketIfNeeded获取到ZygoteState.

 @GuardedBy("mLock")private ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx {try {attemptConnectionToPrimaryZygote();if (primaryZygoteState.matches(abi)) {return primaryZygoteState;}if (mZygoteSecondarySocketAddress != null) {// The primary zygote didn't match. Try the secondary.attemptConnectionToSecondaryZygote();if (secondaryZygoteState.matches(abi)) {return secondaryZygoteState;}}} catch (IOException ioe) {throw new ZygoteStartFailedEx("Error connecting to zygote", ioe);}throw new ZygoteStartFailedEx("Unsupported zygote ABI: " + abi);}

ZygoteState连接:

当主zygote为空或者closed,发起connect()操作

 @GuardedBy("mLock")private void attemptConnectionToPrimaryZygote() throws IOException {if (primaryZygoteState == null || primaryZygoteState.isClosed()) {primaryZygoteState =ZygoteState.connect(mZygoteSocketAddress, mUsapPoolSocketAddress);maybeSetApiBlacklistExemptions(primaryZygoteState, false);maybeSetHiddenApiAccessLogSampleRate(primaryZygoteState);maybeSetHiddenApiAccessStatslogSampleRate(primaryZygoteState);}}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com