本文共 7422 字,大约阅读时间需要 24 分钟。
Activity的启动方式主要有两种,一种是在Launcher界面点击应用图标,另一种是在应用中通过Intent进行跳转。以下将重点介绍后者,即通过Intent启动Activity的流程。
@Overridepublic void startActivity(Intent intent) { this.startActivity(intent, null);}@Overridepublic void startActivity(Intent intent, @Nullable Bundle options) { if (options != null) { startActivityForResult(intent, -1, options); } else { startActivityForResult(intent, -1); }}
最终都会调用startActivityForResult()方法。我们跟进去看看:
public void startActivityForResult(Intent intent, int requestCode, @Nullable Bundle options) { if (mParent == null) { // 转交给Instrumentation来startActivity 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; } // ... 其他代码 ... } else { // ... 其他代码 ... } // ... }
继续进入Instrumentation类,看看execStartActivity方法:
// Instrumentation类public ActivityResult execStartActivity( Context who, IBinder contextThread, IBinder token, Activity target, Intent intent, int requestCode, Bundle options) { IApplicationThread whoThread = (IApplicationThread) contextThread; if (mActivityMonitors != null) { synchronized (mSync) { final int N = mActivityMonitors.size(); for (int i = 0; i < N; i++) { final activitymonitor am = mActivityMonitors.get(i); if (am.match(who, null, intent)) { am.mhits++; if (am.isblocking()) { return am.getResult() ?: null; } } } break; } } try { intent.migrateExtraStreamToClipData(); intent.prepareToLeaveProcess(); // 交给ActivityManagerNative来startActivity int result = ActivityManagerNative.getDefault() .startActivity(whoThread, who.getBasePackageName(), intent, intent.resolveTypeIfNeeded(who.getContentResolver()), token, target != null ? target.mEmbeddedID : null, requestCode, 0, null, options); // 检查启动Activity的结果 checkStartActivityResult(result, intent); } catch (RemoteException e) { } return null;}
ActivityManagerNative是一个Binder对象,实现了IActivityManager接口。其getDefault()方法通过asInterface(IBinder obj)方法构建了ActivityManagerProxy单例。
public abstract class ActivityManagerNative extends Binder implements IActivityManager { static public IActivityManager asInterface(IBinder obj) { if (obj == null) { return null; } IActivityManager in = (IActivityManager) obj.queryLocalInterface(descriptor); if (in != null) { return in; } return new ActivityManagerProxy(obj); } static public IActivityManager getDefault() { return gDefault.get(); } private static final SingletongDefault = new Singleton () { protected IActivityManager create() { IBinder b = ServiceManager.getService("activity"); if (false) { Log.v("ActivityManager", "default service binder = " + b); } IActivityManager am = asInterface(b); if (false) { Log.v("ActivityManager", "default service = " + am); } return am; } };}
看AMS的startActivity()方法:
@Overridepublic final int startActivity(IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle options) { return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, resultWho, requestCode, startFlags, profilerInfo, options, UserHandle.getCallingUserId());}@Overridepublic final int startActivityAsUser(IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { enforceNotIsolatedCaller("startActivity"); userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, false, ALLOW_FULL_ONLY, "startActivity", null); // TODO: Switch to user app stacks here. return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, null, null, options, false, userId, null, null);}
可以看出,Activity启动任务被AMS转交给了ActivityStackSupervisor的startActivityMayWait方法。
ActivityStackSupervisor类中的startActivityMayWait方法调用startActivityLocked()继续执行,而startActivityLocked()方法中又会调用startActivityUncheckedLocked()方法:
final int startActivityMayWait(IApplicationThread caller, int callingUid, String callingPackage, Intent intent, String resolvedType, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, WaitResult outResult, Configuration config, Bundle options, boolean ignoreTargetSecurity, int userId, IActivityContainer iContainer, TaskRecord inTask) { // ... 省略一大片代码 ... int res = startActivityLocked(caller, intent, resolvedType, aInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options, ignoreTargetSecurity, componentSpecified, null, container, inTask); // ... 再省略一大片代码 ...}
跟进它的resumeTopActivityLocked()方法:
final boolean resumeTopActivityLocked(ActivityRecord prev) { return resumeTopActivityLocked(prev, null);}final boolean resumeTopActivityLocked(ActivityRecord prev, Bundle options) { if (mStackSupervisor.inResumeTopActivity) { // Don't even start recursing. return false; } boolean result = false; try { // Protect against recursion. mStackSupervisor.inResumeTopActivity = true; if (mService.mLockScreenShown == ActivityManagerService.LOCK_SCREEN_LEAVING) { mService.mLockScreenShown = ActivityManagerService.LOCK_SCREEN_HIDDEN; mService.updateSleepIfNeededLocked(); } // 注意这里 result = resumeTopActivityInnerLocked(prev, options); } finally { mStackSupervisor.inResumeTopActivity = false; } return result;}
继续看看resumeTopActivityInnerLocked()方法:
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, Bundle options) { // 看这里,又返回交给了ActivityStackSupervisor类 mStackSupervisor.startSpecificActivityLocked(next, true, false); // ... 省略一大片代码 ...}
通过上述步骤,我们可以清晰地看到,从用户触发startActivity()到最终由ActivityManagerService(AMS)通过ActivityStackSupervisor启动Activity的整个流程。
转载地址:http://kcvtz.baihongyu.com/