Android应用程序启动过程(源码分析)

本文相关源代码基于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      }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值