助力软件开发企业降本增效 PHP / java源码系统,只需一次付费,代码终身使用! 广告
本文部分内容摘自《Android开发艺术探索》;部分摘自:[https://www.jianshu.com/p/89fd44083c1c](https://www.jianshu.com/p/89fd44083c1c) # Activity的启动 Activity的startActivity方法有好几种重载方式,但最终都会调用到startActivityForResult方法,如下: ```java // Activity.java public void startActivityForResult(@RequiresPermission Intent intent, int requestCode, @Nullable Bundle options) { if (mParent == null) { options = transferSpringboardActivityOptions(options); Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity( this, mMainThread.getApplicationThread(), mToken, this, intent, requestCode, options); if (ar != null) { mMainThread.sendActivityResult( mToken, mEmbeddedID, requestCode, ar.getResultCode(), ar.getResultData()); } if (requestCode >= 0) { mStartedActivity = true; } cancelInputsAndStartExitTransition(options); } else { if (options != null) { mParent.startActivityFromChild(this, intent, requestCode, options); } else { mParent.startActivityFromChild(this, intent, requestCode); } } } ``` 上面代码中,只需关注mParent==null部分逻辑即可,mParent代表的是ActivityGroup,ActivityGroup最开始被用来在一个界面中嵌入多个子Activity,但在API13中已废弃,改推荐使用Fragment来代替ActivityGroup。 首先看mInstrumentation的execStartActivity方法: ```java // Instrumentation.java public ActivityResult execStartActivity(Context who, IBinder contextThread, IBinder token, Activity target, Intent intent, int requestCode, Bundle options) { IApplicationThread whoThread = (IApplicationThread) contextThread; //... try { intent.migrateExtraStreamToClipData(); intent.prepareToLeaveProcess(who); int result = 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; } ``` 从上面代码看出,启动Activity的真正实现在ActivityTaskManager.getService()的startActivity方法来完成。 > 备注 > 在API29中,调用的是ActivityTaskManager.getService()的startActivity方法 > 在API26-28中,调用的是ActivityManager.getService()的startActivity方法来 > 在API25中,调用的是ActivityManagerNative.getDefault()的startActivity方法 在这里,我们暂时以API26-28中的ActivityManager.getService方法来进行分析。 ```java // ActivityManager.java public static IActivityManager getService() { return IActivityManagerSingleton.get(); } private static final Singleton<IActivityManager> IActivityManagerSingleton = new Singleton<IActivityManager>() { @Override protected IActivityManager create() { final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE); final IActivityManager am = IActivityManager.Stub.asInterface(b); return am; } }; ``` 在getService中使用单例模式获取到IActivityManager对象。其中Singleton类代码如下: ```java // Singleton.java public static class Singleton<T> { private T mInstance; protected abstract T create(); public final T get() { synchronized (this) { if (mInstance == null) { mInstance = create(); } return mInstance; } } } ``` ActivityManager.getService方法拿到的是IActivityManager对象,调用了其startActivity方法进行启动Activity。因为ActivityManagerService类继承了IActivityManager.Stub,所以IActivityManager的实现类就是ActivityManagerService。直接查看ActivityManagerService的startActivity方法,startActivity方法最终调用了startActivityAsUser方法,API28和API26的ActivityManagerService源码也不一样,其中API26的startActivityAsUser如下: ```java // API 26 // ActivityManagerService.java @Override public final int startActivityAsUser(IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) { enforceNotIsolatedCaller("startActivity"); userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, false, ALLOW_FULL_ONLY, "startActivity", null); // TODO: Switch to user app stacks here. return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, null, null, bOptions, false, userId, null, null, "startActivityAsUser"); } ``` API28的startActivityAsUser代码如下: ```java // API 28 // ActivityManagerService.java public final int startActivityAsUser(IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId, boolean validateIncomingUser) { enforceNotIsolatedCaller("startActivity"); userId = mActivityStartController.checkTargetUser(userId, validateIncomingUser, Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser"); // TODO: Switch to user app stacks here. return mActivityStartController.obtainStarter(intent, "startActivityAsUser") .setCaller(caller) .setCallingPackage(callingPackage) .setResolvedType(resolvedType) .setResultTo(resultTo) .setResultWho(resultWho) .setRequestCode(requestCode) .setStartFlags(startFlags) .setProfilerInfo(profilerInfo) .setActivityOptions(bOptions) .setMayWait(userId) .execute(); } ``` 其实API28中的ActivityStartController类对ActivityStarter进行了封装,其中使用了工厂方法构造出ActivityStarter对象,并设置各个参数,最终调用ActivityStarter的execute方法进行执行。我们暂时以API28的源码进行分析。 ```java // ActivityStartController.java ActivityStarter obtainStarter(Intent intent, String reason) { return mFactory.obtain().setIntent(intent).setReason(reason); } ``` 来看看ActivityStarter的execute方法: ```java int execute() { try { if (mRequest.mayWait) { // 需要等待startActivity请求的执行结果 return startActivityMayWait(mRequest.caller, mRequest.callingUid, mRequest.callingPackage, 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); } 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); } } finally { onExecutionComplete(); } } ``` 在API26的startActivityAsUser方法中,调用的就是ActivityStarter的startActivityMayWait方法,所以说API28中新增了不需要等待的情况,其他的调用其实是一样的,那么我们就来看看startActivityMayWait方法: ```java // ActivityStarter.java private ActivityManagerService mService; private ActivityStackSupervisor mSupervisor; private int startActivityMayWait(IApplicationThread caller, int callingUid, String callingPackage, Intent intent, String resolvedType, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, WaitResult outResult, Configuration globalConfig, SafeActivityOptions options, boolean ignoreTargetSecurity, int userId, TaskRecord inTask, String reason, boolean allowPendingRemoteAnimationRegistryLookup) { //... // 获取ResolveInfo ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId, 0 /* matchFlags */, computeResolveFilterUid( callingUid, realCallingUid, mRequest.filterCallingUid)); //... // 获取ActivityInfo ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo); synchronized (mService) { final ActivityStack stack = mSupervisor.mFocusedStack; //... if (aInfo != null && (aInfo.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0 && mService.mHasHeavyWeightFeature) { if (aInfo.processName.equals(aInfo.applicationInfo.packageName)) { //... } } final ActivityRecord[] outRecord = new ActivityRecord[1]; // 调用startActivity int res = startActivity(caller, intent, ephemeralIntent, resolvedType, aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options, ignoreTargetSecurity, componentSpecified, outRecord, inTask, reason, allowPendingRemoteAnimationRegistryLookup); //... if (outResult != null) { outResult.result = res; final ActivityRecord r = outRecord[0]; switch(res) { case START_SUCCESS: { //... break; } case START_DELIVERED_TO_TOP: { //... break; } case START_TASK_TO_FRONT: { //... break; } } } mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(res, outRecord[0]); return res; } } ``` 可以看到,首先通过ActivityStackSupervisor来获得ResolveInfo、ActivityInfo后并更新设置,然后调用startActivity方法: ```java // ActivityStarter.java // 此方法主要是为了初始化reason 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, String reason, boolean allowPendingRemoteAnimationRegistryLookup) { mLastStartReason = reason; //... mLastStartActivityResult = startActivity(caller, intent, ephemeralIntent, resolvedType, aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options, ignoreTargetSecurity, componentSpecified, mLastStartActivityRecord, inTask, allowPendingRemoteAnimationRegistryLookup); //... return getExternalResult(mLastStartActivityResult); } 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) { //... return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags, true /* doResume */, checkedOptions, inTask, outActivity); } private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask, ActivityRecord[] outActivity) { int result = START_CANCELED; try { mService.mWindowManager.deferSurfaceLayout(); result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor, startFlags, doResume, options, inTask, outActivity); } finally { //... } //... return result; } private ActivityStack mTargetStack; private ActivityStackSupervisor mSupervisor; private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask, ActivityRecord[] outActivity) { //... mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity, mOptions); //... return START_SUCCESS; } ``` ActivityStarter的startActivity方法最终会调用到startActivityUnchecked方法,在该方法中会**根据启动标志位和Activity启动模式来决定如何启动一个Activity以及是否要调用deliverNewIntent方法通知Activity有一个Intent试图重新启动它**,最终会调用ActivityStackSupervisor的resumeFocusedStackTopActivityLocked方法: ```java // ActivityStackSupervisor.java boolean resumeFocusedStackTopActivityLocked(ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) { if (!readyToResume()) { return false; } if (targetStack != null && isFocusedStack(targetStack)) { return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions); } //... return false; } ``` 调用ActivityStack的resumeTopActivityUncheckedLocked方法: ```java // ActivityStack.java boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) { //... result = resumeTopActivityInnerLocked(prev, options); return result; } private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) { //... boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, next, false); if (mResumedActivity != null) { pausing |= startPausingLocked(userLeaving, false, next, false); } //... mStackSupervisor.startSpecificActivityLocked(next, true, true); //... return true; } ``` > **在ActivityStack.resumeTopActivityInnerLocked方法中会去判断是否有Activity处于Resume状态,如果有的话会先让这个Activity执行Pausing过程,然后再执行startSpecificActivityLocked方法启动要启动Activity。** startSpecificActivityLocked方法代码如下: ```java // ActivityStackSupervisor.java void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) { ProcessRecord app = mService.getProcessRecordLocked(r.processName, r.info.applicationInfo.uid, true); getLaunchTimeTracker().setLaunchTime(r); if (app != null && app.thread != null) { try { if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0 || !"android".equals(r.info.packageName)) { app.addPackage(r.info.packageName, r.info.applicationInfo.longVersionCode, mService.mProcessStats); } realStartActivityLocked(r, app, andResume, checkConfig); return; } catch (RemoteException e) { Slog.w(TAG, "Exception when starting activity " + r.intent.getComponent().flattenToShortString(), e); } } mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0, "activity", r.intent.getComponent(), false, false, true); } ``` > 在startSpecificActivityLocked方法中会去根据进程和线程是否存在判断App是否已经启动,如果已经启动,就会调用realStartActivityLocked方法继续处理。如果没有启动则调用ActivityManagerService.startProcessLocked方法创建新的进程处理。 首先来看AMS的startProcessLocked方法: ```java // ActivityManagerService.java private ProcessStartResult startProcess(String hostingType, String entryPoint, ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal, String seInfo, String requiredAbi, String instructionSet, String invokeWith, long startTime) { //... startResult = Process.start(entryPoint, app.processName, uid, uid, gids, runtimeFlags, mountExternal, app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet, app.info.dataDir, invokeWith, new String[] {PROC_START_SEQ_IDENT + app.startSeq}); } ``` 调用了Process的start方法: ```java // /frameworks/base/core/java/android/os/Process.java public static final ProcessStartResult start(final String processClass, final String niceName, int uid, int gid, int[] gids, int runtimeFlags, int mountExternal, int targetSdkVersion, String seInfo, String abi, String instructionSet, String appDataDir, String invokeWith, String[] zygoteArgs) { return zygoteProcess.start(processClass, niceName, uid, gid, gids, runtimeFlags, mountExternal, targetSdkVersion, seInfo, abi, instructionSet, appDataDir, invokeWith, zygoteArgs); } ``` 调用了ZygoteProcess的start方法: ```java // ZygoteProcess.java // ZygoteProcess.java public final Process.ProcessStartResult start(final String processClass, final String niceName, int uid, int gid, int[] gids, int runtimeFlags, int mountExternal, int targetSdkVersion, String seInfo, String abi, String instructionSet, String appDataDir, String invokeWith, String[] zygoteArgs) { try { return startViaZygote(processClass, niceName, uid, gid, gids, runtimeFlags, mountExternal, targetSdkVersion, seInfo, abi, instructionSet, appDataDir, invokeWith, false /* startChildZygote */, zygoteArgs); } catch (ZygoteStartFailedEx ex) { Log.e(LOG_TAG, "Starting VM process through Zygote failed"); throw new RuntimeException( "Starting VM process through Zygote failed", ex); } } private Process.ProcessStartResult startViaZygote(final String processClass, final String niceName, final int uid, final int gid, final int[] gids, int runtimeFlags, int mountExternal, int targetSdkVersion, String seInfo, String abi, String instructionSet, String appDataDir, String invokeWith, boolean startChildZygote, String[] extraArgs) throws ZygoteStartFailedEx { //... synchronized(mLock) { return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote); } } /** * Tries to open socket to Zygote process if not already open. If * already open, does nothing. May block and retry. Requires that mLock be held. * 尝试通过Socket建立和Zygote的连接 */ private ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx { Preconditions.checkState(Thread.holdsLock(mLock), "ZygoteProcess lock not held"); if (primaryZygoteState == null || primaryZygoteState.isClosed()) { try { primaryZygoteState = ZygoteState.connect(mSocket); } catch (IOException ioe) { throw new ZygoteStartFailedEx("Error connecting to primary zygote", ioe); } maybeSetApiBlacklistExemptions(primaryZygoteState, false); maybeSetHiddenApiAccessLogSampleRate(primaryZygoteState); } if (primaryZygoteState.matches(abi)) { return primaryZygoteState; } // The primary zygote didn't match. Try the secondary. if (secondaryZygoteState == null || secondaryZygoteState.isClosed()) { try { secondaryZygoteState = ZygoteState.connect(mSecondarySocket); } catch (IOException ioe) { throw new ZygoteStartFailedEx("Error connecting to secondary zygote", ioe); } maybeSetApiBlacklistExemptions(secondaryZygoteState, false); maybeSetHiddenApiAccessLogSampleRate(secondaryZygoteState); } if (secondaryZygoteState.matches(abi)) { return secondaryZygoteState; } throw new ZygoteStartFailedEx("Unsupported zygote ABI: " + abi); } ``` > 经过一步步调用,可以发现其最终**调用了Zygote并通过socket通信的方式让Zygote进程fork出一个新的进程,并根据传递的”android.app.ActivityThread”字符串,反射出该对象并执行ActivityThread的main方法对其进行初始化。**