}
// github.com/amirzaidi/L… protected void onClickAppShortcut(final View v) { ... // Start activities startAppShortcutOrInfoActivity(v); }
// github.com/amirzaidi/L… private void startAppShortcutOrInfoActivity(View v) { ItemInfo item = (ItemInfo) v.getTag(); Intent intent;// 应用程序安装的时候根据 AndroidManifest.xml 由 PackageManagerService 解析并保存的 if (item instanceof PromiseAppInfo) { PromiseAppInfo promiseAppInfo = (PromiseAppInfo) item; intent = promiseAppInfo.getMarketIntent(); } else { intent = item.getIntent(); } ... boolean success = startActivitySafely(v, intent, item); ... }
// github.com/amirzaidi/L… public boolean startActivitySafely(View v, Intent intent, ItemInfo item) { ... intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); ... startActivity(intent, optsBundle); ... }
2. 以 API 27 源码为例,说到了 Acitvity#startActivity,我们点击源码可以发现调用的是 Activity#startActivityForResult,其中调用到了 Instrumentation#execStartActivity 这个方法,源码如下所示:
// androidxref.com/8.1.0_r33/x… public void startActivity(Intent intent, @Nullable Bundle options) { 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); } }
// androidxref.com/8.1.0_r33/x… public void startActivityForResult(@RequiresPermission Intent intent, int requestCode, @Nullable Bundle options) { ... Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity( this, mMainThread.getApplicationThread(), mToken, this, intent, requestCode, options); ... }
3. 在 Instrumentation#execStartActivity 中我们可以发现它调用了 ActivityManager#getService()#startActivity,其 ActivityManager#getService() 是采用单例,返回的是实现 IActivityManager 类型的 Binder 对象,它的具体实现是在 ActivityManagerService 中。
// androidxref.com/8.1.0_r33/x… public ActivityResult execStartActivity( Context who, IBinder contextThread, IBinder token, Activity target, Intent intent, int requestCode, Bundle options) { ... try { ... int result = ActivityManager.getService() .startActivity(whoThread, who.getBasePackageName(), intent, intent.resolveTypeIfNeeded(who.getContentResolver()), token, target != null ? target.mEmbeddedID : null, requestCode, 0, null, options); ... } catch (RemoteException e) { ... } return null; }
// androidxref.com/8.1.0_r33/x… public static IActivityManager getService() { return IActivityManagerSingleton.get(); } private static final Singleton IActivityManagerSingleton = new Singleton() { @Override protected IActivityManager create() { final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE); final IActivityManager am = IActivityManager.Stub.asInterface(b); return am; } };
4. 我们再到 ActivityManagerService#startActivity 查看其源码,发现其调用了 ActivityManagerService#startActivityAsUser,该方法又调用了 ActivityStarter#startActivityMayWait,源码如下所示:
// androidxref.com/8.1.0_r33/x… @Override public 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()); }
@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, "startActivityAsUser"); }
5. 我们查找到 ActivityStarter#startActivityMayWait,其间调用了 ActivityStarter#startActivityLocked,接着是 ActivityStarter#startActivity,然后是 ActivityStarter#startActivityUnchecked,其调用了 ActivityStackSupervisor#resumeFocusedStackTopActivityLocked,源码如下所示:
// androidxref.com/8.1.0_r33/x… 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 globalConfig, Bundle bOptions, boolean ignoreTargetSecurity, int userId, TaskRecord inTask, String reason) { ... int res = startActivityLocked(caller, intent, ephemeralIntent, resolvedType, aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options, ignoreTargetSecurity, componentSpecified, outRecord, inTask, reason); ... } // androidxref.com/8.1.0_r33/x… int startActivityLocked(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, ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity, TaskRecord inTask, String 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); }
// androidxref.com/8.1.0_r33/x… 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, ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity, TaskRecord inTask) { ... return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags, true, options, inTask, outActivity); }
// androidxref.com/8.1.0_r33/x… private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask, ActivityRecord[] outActivity) { ... result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor, startFlags, doResume, options, inTask, outActivity); ... }
// androidxref.com/8.1.0_r33/x… 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); ... }
6. 到 ActivityStackSupervisor#resumeFocusedStackTopActivityLocked 中查看发现其调用了 ActivityStack#resumeTopActivityUncheckedLocked,然后是 ActivityStack#resumeTopActivityInnerLocked,接着变又回到 ActivityStackSupervisor.java,调用了 ActivityStackSupervisor#startSpecificActivityLocked,这个方法中会判断要启动 App 的进程是否存在,存在则通知进程启动 Activity,否则就先将进程创建出来,其源码如下所示:
// androidxref.com/8.1.0_r33/x… boolean resumeFocusedStackTopActivityLocked( ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) { ... return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions); ... }
// androidxref.com/8.1.0_r33/x… boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) { ... result = resumeTopActivityInnerLocked(prev, options); ... }
androidxref.com/8.1.0_r33/x… private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) { ... mStackSupervisor.startSpecificActivityLocked(next, true, true); ... }
// androidxref.com/8.1.0_r33/x… void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) { ... if (app != null && app.thread != null) { ... // 如果进程已存在,则通知进程启动组件 realStartActivityLocked(r, app, andResume, checkConfig); return; ... } // 否则先将进程创建出来 mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0, "activity", r.intent.getComponent(), false, false, true); ... }
7. 我们分析进程尚未存在的情况,因为我们后续还会再次遇到 ActivityStackSupervisor#realStartActivityLocked,ActivityStackSupervisor#startSpecificActivityLocked 中创建进程使用到的 mService 为 ActivityManagerService,我们查看 ActivityManagerService#startProcessLocked 的源码如下所示:
// androidxref.com/8.1.0_r33/x… private final void startProcessLocked(ProcessRecord app, String hostingType, String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) { ... if (entryPoint == null) entryPoint = "android.app.ActivityThread"; startResult = Process.start(entryPoint, app.processName, uid, uid, gids, debugFlags, mountExternal, app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet, app.info.dataDir, invokeWith, entryPointArgs); ... }
8. 发现最终调用的事 Process#start 来启动进程,进程的入口就是在 android.app.ActivityThread.java 类中的 main() 函数,因此接下来我们从 ActivityThread#main 来分析,其调用了 ActivityThread#attach,其中 ActivityManager.getService() 之前提到过,返回的是一个是实现 IActivityManager 类型的 Binder 对象,它的具体实现是在 ActivityManagerService 中,相关源码如下所示:
// androidxref.com/8.1.0_r33/x… public static void main(String[] args) { ... Looper.prepareMainLooper();
ActivityThread thread = new ActivityThread(); thread.attach(false); ... Looper.loop(); ... }
// androidxref.com/8.1.0_r33/x… private void attach(boolean system) { sCurrentActivityThread = this; mSystemThread = system; if (!system) { ... final IActivityManager mgr = ActivityManager.getService(); try { mgr.attachApplication(mAppThread); } catch (RemoteException ex) { ... } ... } ... }
9. 我们又回到了 ActivityManagerService 中,查看其 attachApplication 函数,发现调用了 thread#bindApplication 和 mStackSupervisor#attachApplicationLocked 我们依次讲解这两个方法要做的事情,源码如下所示:
// androidxref.com/8.1.0_r33/x… public final void attachApplication(IApplicationThread thread) { ... attachApplicationLocked(thread, callingPid); ... }
// androidxref.com/8.1.0_r33/x… private final boolean attachApplicationLocked(IApplicationThread thread, int pid) { .... thread.bindApplication(processName, appInfo, providers, app.instr.mClass, profilerInfo, app.instr.mArguments, app.instr.mWatcher, app.instr.mUiAutomationConnection, testMode, mBinderTransactionTrackingEnabled, enableTrackAllocation, isRestrictedBackupMode || !normalMode, app.persistent, new Configuration(getGlobalConfiguration()), app.compat, getCommonServicesLocked(app.isolated), mCoreSettingsObserver.getCoreSettingsLocked(), buildSerial); ... if (normalMode) { try { if (mStackSupervisor.attachApplicationLocked(app)) { didSomething = true; } } catch (Exception e) { ... } } ... }
10. 上面说到的thread#bindApplication 中的这个 thread 是来自于 ActivityThread#mAppThread,其类型是 ApplicationThread,是 ActivityThread 的一个内部类,继承自 IApplicationThread.Stub,我们来查看 ApplicationThread#bindApplication,发现最后调用了 ActivityThread#sendMessage 方法,它内部调用了 mH.sendMessage 来发送消息,mH 是 ActivityThread 的内部类 H 的一个实例,查看 H#handleMessage 来查看它是怎么处理发送过来的消息,其最终走到了 ActivityThread#handleBindApplication。
在源码中我们可以发现它先创建 mInstrumentation 对象,调用 data#info#makeApplication 来创建 Application 对象,其对象 data#info 为 LoadedApk 的一个实例,查看 LoadedApk#makeApplication 中代码可以发现,其调用了 Instrumentation#newApplication 方法,内部靠 Class#newInstance() 完成对 Application 实例化,然后调用 Application#attach(context) 来绑定 Context。
以上创建完 Application 对象后便是调用 Instrumentation#callApplicationOnCreate 走 Application 的 onCreate 生命周期,以上涉及到的全部源码如下所示:
// androidxref.com/8.1.0_r33/x… public final void bindApplication(String processName, ApplicationInfo appInfo, List providers, 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) { ... sendMessage(H.BIND_APPLICATION, data); }
// androidxref.com/8.1.0_r33/x… private void sendMessage(int what, Object obj) { sendMessage(what, obj, 0, 0, false); }
private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) { if (DEBUG_MESSAGES) Slog.v( TAG, "SCHEDULE " + what + " " + mH.codeToString(what)
- ": " + arg1 + " / " + obj); Message msg = Message.obtain(); msg.what = what; msg.obj = obj; msg.arg1 = arg1; msg.arg2 = arg2; if (async) { msg.setAsynchronous(true); } mH.sendMessage(msg); }
// androidxref.com/8.1.0_r33/x… public void handleMessage(Message msg) { ... 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; ... } }
// androidxref.com/8.1.0_r33/x… private void handleBindApplication(AppBindData data) { ... final InstrumentationInfo ii; ... // 创建 mInstrumentation 实例 if (ii != null) { final ApplicationInfo instrApp = new ApplicationInfo(); ii.copyTo(instrApp); instrApp.initForUser(UserHandle.myUserId()); final LoadedApk pi = getPackageInfo(instrApp, data.compatInfo, appContext.getClassLoader(), false, true, false); final ContextImpl instrContext = ContextImpl.createAppContext(this, pi);
try { final ClassLoader cl = instrContext.getClassLoader(); mInstrumentation = (Instrumentation) cl.loadClass(data.instrumentationName.getClassName()).newInstance(); } catch (Exception e) { ... } ... } else { mInstrumentation = new Instrumentation(); } ... Application app; ... // 创建 Application 实例 try { ... app = data.info.makeApplication(data.restrictedBackupMode, null); mInitialApplication = app; ... try { mInstrumentation.callApplicationOnCreate(app); } catch (Exception e) { ... } } finally { ... } ... }
// androidxref.com/8.1.0_r33/x… public Application makeApplication(boolean forceDefaultAppClass, Instrumentation instrumentation) { Application app = null;
String appClass = mApplicationInfo.className; if (forceDefaultAppClass || (appClass == null)) { appClass = "android.app.Application"; }
try { java.lang.ClassLoader cl = getClassLoader(); ... ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this); app = mActivityThread.mInstrumentation.newApplication( cl, appClass, appContext);