本文相关源代码基于Android11
Launcher启动后会将已安装应用程序的快捷图标显示到界面上,当我们点击应用程序的快捷图标时就会调用Launcher的startActivitySafely方法,如下所示:
packages/apps/Launcher3/src/com/android/launcher3/Launcher.java
@Override
1881 public boolean startActivitySafely(View v, Intent intent, ItemInfo item,
1882 @Nullable String sourceContainer) {
1883 if (!hasBeenResumed()) {
1884 // Workaround an issue where the WM launch animation is clobbered when finishing the
1885 // recents animation into launcher. Defer launching the activity until Launcher is
1886 // next resumed.
1887 addOnResumeCallback(() -> startActivitySafely(v, intent, item, sourceContainer));
1888 if (mOnDeferredActivityLaunchCallback != null) {
1889 mOnDeferredActivityLaunchCallback.run();
1890 mOnDeferredActivityLaunchCallback = null;
1891 }
1892 return true;
1893 }
1894
1895 boolean success = super.startActivitySafely(v, intent, item, sourceContainer);
1896 if (success && v instanceof BubbleTextView) {
1897 // This is set to the view that launched the activity that navigated the user away
1898 // from launcher. Since there is no callback for when the activity has finished
1899 // launching, enable the press state and keep this reference to reset the press
1900 // state when we return to launcher.
1901 BubbleTextView btv = (BubbleTextView) v;
1902 btv.setStayPressed(true);
1903 addOnResumeCallback(btv);
1904 }
1905 return success;
1906 }
由代码1895可知,进入了父类的方法,直接父类StatefulActivity没有该方法实现,进入下一父类 BaseDraggingActivity:
public boolean startActivitySafely(View v, Intent intent, @Nullable ItemInfo item,
169 @Nullable String sourceContainer) {
170 if (mIsSafeModeEnabled && !PackageManagerHelper.isSystemApp(this, intent)) {
171 Toast.makeText(this, R.string.safemode_shortcut_error, Toast.LENGTH_SHORT).show();
172 return false;
173 }
174
175 Bundle optsBundle = (v != null) ? getActivityLaunchOptionsAsBundle(v) : null;
176 UserHandle user = item == null ? null : item.user;
177
178 // Prepare intent
179 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
180 if (v != null) {
181 intent.setSourceBounds(getViewBounds(v));
182 }
183 try {
184 boolean isShortcut = (item instanceof WorkspaceItemInfo)
185 && (item.itemType == Favorites.ITEM_TYPE_SHORTCUT
186 || item.itemType == Favorites.ITEM_TYPE_DEEP_SHORTCUT)
187 && !((WorkspaceItemInfo) item).isPromise();
188 if (isShortcut) {
189 // Shortcuts need some special checks due to legacy reasons.
190 startShortcutIntentSafely(intent, optsBundle, item, sourceContainer);
191 } else if (user == null || user.equals(Process.myUserHandle())) {
192 // Could be launching some bookkeeping activity
193 startActivity(intent, optsBundle);
194 AppLaunchTracker.INSTANCE.get(this).onStartApp(intent.getComponent(),
195 Process.myUserHandle(), sourceContainer);
196 } else {
197 getSystemService(LauncherApps.class).startMainActivity(
198 intent.getComponent(), user, intent.getSourceBounds(), optsBundle);
199 AppLaunchTracker.INSTANCE.get(this).onStartApp(intent.getComponent(), user,
200 sourceContainer);
201 }
202 getUserEventDispatcher().logAppLaunch(v, intent, user);
203 if (item != null) {
204 InstanceId instanceId = new InstanceIdSequence().newInstanceId();
205 logAppLaunch(item, instanceId);
206 }
207 return true;
208 } catch (NullPointerException|ActivityNotFoundException|SecurityException e) {
209 Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
210 Log.e(TAG, "Unable to launch. tag=" + item + " intent=" + intent, e);
211 }
212 return false;
213 }
在179行处设置Flag为Intent.FLAG_ACTIVITY_NEW_TASK,这样根Activity会在新的任务栈中启动。在193行处调用了startActivity函数:
@Override
5643 public void startActivity(Intent intent, @Nullable Bundle options) {
5644 if (mIntent != null && mIntent.hasExtra(AutofillManager.EXTRA_RESTORE_SESSION_TOKEN)
5645 && mIntent.hasExtra(AutofillManager.EXTRA_RESTORE_CROSS_ACTIVITY)) {
5646 if (TextUtils.equals(getPackageName(),
5647 intent.resolveActivity(getPackageManager()).getPackageName())) {
5648 // Apply Autofill restore mechanism on the started activity by startActivity()
5649 final IBinder token =
5650 mIntent.getIBinderExtra(AutofillManager.EXTRA_RESTORE_SESSION_TOKEN);
5651 // Remove restore ability from current activity
5652 mIntent.removeExtra(AutofillManager.EXTRA_RESTORE_SESSION_TOKEN);
5653 mIntent.removeExtra(AutofillManager.EXTRA_RESTORE_CROSS_ACTIVITY);
5654 // Put restore token
5655 intent.putExtra(AutofillManager.EXTRA_RESTORE_SESSION_TOKEN, token);
5656 intent.putExtra(AutofillManager.EXTRA_RESTORE_CROSS_ACTIVITY, true);
5657 }
5658 }
5659 if (options != null) {
5660 startActivityForResult(intent, -1, options);
5661 } else {
5662 // Note we want to go through this call for compatibility with
5663 // applications that may have overridden the method.
5664 startActivityForResult(intent, -1);
5665 }
5666 }
startActivity会调用startActivityForResult函数,其中第二个参数为-1,表示Launcher不需要知道Activity启动的结果,startActivityForResult函数的代码如下所示:
@Override
6029 @UnsupportedAppUsage
6030 public void startActivityForResult(
6031 String who, Intent intent, int requestCode, @Nullable Bundle options) {
6032 Uri referrer = onProvideReferrer();
6033 if (referrer != null) {
6034 intent.putExtra(Intent.EXTRA_REFERRER, referrer);
6035 }
6036 options = transferSpringboardActivityOptions(options);
6037 Instrumentation.ActivityResult ar =
6038 mInstrumentation.execStartActivity(
6039 this, mMainThread.getApplicationThread(), mToken, who,
6040 intent, requestCode, options);
6041 if (ar != null) {
6042 mMainThread.sendActivityResult(
6043 mToken, who, requestCode,
6044 ar.getResultCode(), ar.getResultData());
6045 }
6046 cancelInputsAndStartExitTransition(options);
6047 }
调用Instrumentation的execStartActivity方法,Instrumentation主要用来监控应用程序和系统的交互,execStartActivity方法的代码如下所示:
@UnsupportedAppUsage
1690 public ActivityResult execStartActivity(
1691 Context who, IBinder contextThread, IBinder token, Activity target,
1692 Intent intent, int requestCode, Bundle options) {
1693 IApplicationThread whoThread = (IApplicationThread) contextThread;
1694 Uri referrer = target != null ? target.onProvideReferrer() : null;
1695 if (referrer != null) {
1696 intent.putExtra(Intent.EXTRA_REFERRER, referrer);
1697 }
1698 if (mActivityMonitors != null) {
1699 synchronized (mSync) {
1700 final int N = mActivityMonitors.size();
1701 for (int i=0; i<N; i++) {
1702 final ActivityMonitor am = mActivityMonitors.get(i);
1703 ActivityResult result = null;
1704 if (am.ignoreMatchingSpecificIntents()) {
1705 result = am.onStartActivity(intent);
1706 }
1707 if (result != null) {
1708 am.mHits++;
1709 return result;
1710 } else if (am.match(who, null, intent)) {
1711 am.mHits++;
1712 if (am.isBlocking()) {
1713 return requestCode >= 0 ? am.getResult() : null;
1714 }
1715 break;
1716 }
1717 }
1718 }
1719 }
1720 try {
1721 intent.migrateExtraStreamToClipData(who);
1722 intent.prepareToLeaveProcess(who);
1723 int result = ActivityTaskManager.getService().startActivity(whoThread,
1724 who.getBasePackageName(), who.getAttributionTag(), intent,
1725 intent.resolveTypeIfNeeded(who.getContentResolver()), token,
1726 target != null ? target.mEmbeddedID : null, requestCode, 0, null, options);
1727 checkStartActivityResult(result, intent);
1728 } catch (RemoteException e) {
1729 throw new RuntimeException("Failure from system", e);
1730 }
1731 return null;
1732 }
首先会调用ActivityTaskManager的getService()来获取ActivityTaskManager的代理对象,接着调用它的startActivity方法。首先我们先来查看ActivityTaskManager的getDefault方法做了什么:
@Override
1039 public final int startActivity(IApplicationThread caller, String callingPackage,
1040 String callingFeatureId, Intent intent, String resolvedType, IBinder resultTo,
1041 String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo,
1042 Bundle bOptions) {
1043 return startActivityAsUser(caller, callingPackage, callingFeatureId, intent, resolvedType,
1044 resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions,
1045 UserHandle.getCallingUserId());
1046 }
@Override
1064 public int startActivityAsUser(IApplicationThread caller, String callingPackage,
1065 String callingFeatureId, Intent intent, String resolvedType, IBinder resultTo,
1066 String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo,
1067 Bundle bOptions, int userId) {
1068 return startActivityAsUser(caller, callingPackage, callingFeatureId, intent, resolvedType,
1069 resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,
1070 true /*validateIncomingUser*/);
1071 }
1072
1073 private int startActivityAsUser(IApplicationThread caller, String callingPackage,
1074 @Nullable String callingFeatureId, Intent intent, String resolvedType,
1075 IBinder resultTo, String resultWho, int requestCode, int startFlags,
1076 ProfilerInfo profilerInfo, Bundle bOptions, int userId, boolean validateIncomingUser) {
1077 assertPackageMatchesCallingUid(callingPackage);
1078 enforceNotIsolatedCaller("startActivityAsUser");
1079
1080 userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
1081 Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
1082
1083 // TODO: Switch to user app stacks here.
1084 return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
1085 .setCaller(caller)
1086 .setCallingPackage(callingPackage)
1087 .setCallingFeatureId(callingFeatureId)
1088 .setResolvedType(resolvedType)
1089 .setResultTo(resultTo)
1090 .setResultWho(resultWho)
1091 .setRequestCode(requestCode)
1092 .setStartFlags(startFlags)
1093 .setProfilerInfo(profilerInfo)
1094 .setActivityOptions(bOptions)
1095 .setUserId(userId)
1096 .execute();
1097
1098 }
在ATMS接收到消息后,先后执行startActivity->startActivityAsUser->startActivityAsUser方法,通过getActivityStartController().obtainStarter获取ActivityStarter实例,去执行execute方法,继续向下走。
int execute() {
629 try {
630 // Refuse possible leaked file descriptors
631 if (mRequest.intent != null && mRequest.intent.hasFileDescriptors()) {
632 throw new IllegalArgumentException("File descriptors passed in Intent");
633 }
634
635 final LaunchingState launchingState;
636 synchronized (mService.mGlobalLock) {
637 final ActivityRecord caller = ActivityRecord.forTokenLocked(mRequest.resultTo);
638 launchingState = mSupervisor.getActivityMetricsLogger().notifyActivityLaunching(
639 mRequest.intent, caller);
640 }
641
642 // If the caller hasn't already resolved the activity, we're willing
643 // to do so here. If the caller is already holding the WM lock here,
644 // and we need to check dynamic Uri permissions, then we're forced
645 // to assume those permissions are denied to avoid deadlocking.
646 if (mRequest.activityInfo == null) {
647 mRequest.resolveActivity(mSupervisor);
648 }
649
650 int res;
651 synchronized (mService.mGlobalLock) {
652 final boolean globalConfigWillChange = mRequest.globalConfig != null
653 && mService.getGlobalConfiguration().diff(mRequest.globalConfig) != 0;
654 final ActivityStack stack = mRootWindowContainer.getTopDisplayFocusedStack();
655 if (stack != null) {
656 stack.mConfigWillChange = globalConfigWillChange;
657 }
658 if (DEBUG_CONFIGURATION) {
659 Slog.v(TAG_CONFIGURATION, "Starting activity when config will change = "
660 + globalConfigWillChange);
661 }
662
663 final long origId = Binder.clearCallingIdentity();
664
665 res = resolveToHeavyWeightSwitcherIfNeeded();
666 if (res != START_SUCCESS) {
667 return res;
668 }
669 res = executeRequest(mRequest);
670
671 Binder.restoreCallingIdentity(origId);
672
673 if (globalConfigWillChange) {
674 // If the caller also wants to switch to a new configuration, do so now.
675 // This allows a clean switch, as we are waiting for the current activity
676 // to pause (so we will not destroy it), and have not yet started the
677 // next activity.
678 mService.mAmInternal.enforceCallingPermission(
679 android.Manifest.permission.CHANGE_CONFIGURATION,
680 "updateConfiguration()");
681 if (stack != null) {
682 stack.mConfigWillChange = false;
683 }
684 if (DEBUG_CONFIGURATION) {
685 Slog.v(TAG_CONFIGURATION,
686 "Updating to new configuration after starting activity.");
687 }
688 mService.updateConfigurationLocked(mRequest.globalConfig, null, false);
689 }
690
691 // Notify ActivityMetricsLogger that the activity has launched.
692 // ActivityMetricsLogger will then wait for the windows to be drawn and populate
693 // WaitResult.
694 mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(launchingState, res,
695 mLastStartActivityRecord);
696 return getExternalResult(mRequest.waitResult == null ? res
697 : waitForResult(res, mLastStartActivityRecord));
698 }
699 } finally {
700 onExecutionComplete();
701 }
702 }