学习Activity启动流程

来源:互联网 发布:淘宝上买的弹弓枪 编辑:程序博客网 时间:2024/05/21 11:19
1.startActivity(intent)
  1. @Override
  2. public void startActivity(Intent intent) {
  3. this.startActivity(intent, null);
  4. }
2.调用 startActivity(intent,null)
  1. @Override
  2. public void startActivity(Intent intent, @Nullable Bundle options) {
  3. if (options != null) {
  4. startActivityForResult(intent, -1, options);
  5. } else {
  6. // Note we want to go through this call for compatibility with
  7. // applications that may have overridden the method.
  8. startActivityForResult(intent, -1);
  9. }
  10. }
3.调用 startActivityForResult
  1. public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
  2. @Nullable Bundle options) {
  3. if (mParent == null) {
  4. Instrumentation.ActivityResult ar =
  5. mInstrumentation.execStartActivity(
  6. this, mMainThread.getApplicationThread(), mToken, this,
  7. intent, requestCode, options);
  8. if (ar != null) {
  9. mMainThread.sendActivityResult(
  10. mToken, mEmbeddedID, requestCode, ar.getResultCode(),
  11. ar.getResultData());
  12. }
  13. if (requestCode >= 0) {
  14. // If this start is requesting a result, we can avoid making
  15. // the activity visible until the result is received. Setting
  16. // this code during onCreate(Bundle savedInstanceState) or onResume() will keep the
  17. // activity hidden during this time, to avoid flickering.
  18. // This can only be done when a result is requested because
  19. // that guarantees we will get information back when the
  20. // activity is finished, no matter what happens to it.
  21. mStartedActivity = true;
  22. }
  23. cancelInputsAndStartExitTransition(options);
  24. // TODO Consider clearing/flushing other event sources and events for child windows.
  25. } else {
  26. if (options != null) {
  27. mParent.startActivityFromChild(this, intent, requestCode, options);
  28. } else {
  29. // Note we want to go through this method for compatibility with
  30. // existing applications that may have overridden it.
  31. mParent.startActivityFromChild(this, intent, requestCode);
  32. }
  33. }
  34. }
4.mInstrumentation
  1. private Instrumentation mInstrumentation;
5.找到execStartActivity方法
  1. public ActivityResult execStartActivity(
  2. Context who, IBinder contextThread, IBinder token, Activity target,
  3. Intent intent, int requestCode, Bundle options) {
  4. IApplicationThread whoThread = (IApplicationThread) contextThread;
  5. Uri referrer = target != null ? target.onProvideReferrer() : null;
  6. if (referrer != null) {
  7. intent.putExtra(Intent.EXTRA_REFERRER, referrer);
  8. }
  9. if (mActivityMonitors != null) {
  10. synchronized (mSync) {
  11. final int N = mActivityMonitors.size();
  12. for (int i=0; i<N; i++) {
  13. final ActivityMonitor am = mActivityMonitors.get(i);
  14. if (am.match(who, null, intent)) {
  15. am.mHits++;
  16. if (am.isBlocking()) {
  17. return requestCode >= 0 ? am.getResult() : null;
  18. }
  19. break;
  20. }
  21. }
  22. }
  23. }
  24. try {
  25. intent.migrateExtraStreamToClipData();
  26. intent.prepareToLeaveProcess(who);
  27. int result = ActivityManagerNative.getDefault()
  28. .startActivity(whoThread, who.getBasePackageName(), intent,
  29. intent.resolveTypeIfNeeded(who.getContentResolver()),
  30. token, target != null ? target.mEmbeddedID : null,
  31. requestCode, 0, null, options);
  32. checkStartActivityResult(result, intent);
  33. } catch (RemoteException e) {
  34. throw new RuntimeException("Failure from system", e);
  35. }
  36. return null;
  37. }
6.ActivityManagerNative 这边有服务端的东西
ActivityManagerNative.getDefault()

查看startActivity 写入东西
  1. class ActivityManagerProxy implements IActivityManager
  2. {
  1. public int startActivity(IApplicationThread caller, String callingPackage, Intent intent,
  2. String resolvedType, IBinder resultTo, String resultWho, int requestCode,
  3. int startFlags, ProfilerInfo profilerInfo, Bundle options) throws RemoteException {
  4. Parcel data = Parcel.obtain();
  5. Parcel reply = Parcel.obtain();
  6. data.writeInterfaceToken(IActivityManager.descriptor);
  7. data.writeStrongBinder(caller != null ? caller.asBinder() : null);
  8. data.writeString(callingPackage);
  9. intent.writeToParcel(data, 0);
  10. data.writeString(resolvedType);
  11. data.writeStrongBinder(resultTo);
  12. data.writeString(resultWho);
  13. data.writeInt(requestCode);
  14. data.writeInt(startFlags);
  15. if (profilerInfo != null) {
  16. data.writeInt(1);
  17. profilerInfo.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
  18. } else {
  19. data.writeInt(0);
  20. }
  21. if (options != null) {
  22. data.writeInt(1);
  23. options.writeToParcel(data, 0);
  24. } else {
  25. data.writeInt(0);
  26. }
  27. mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);
  28. reply.readException();
  29. int result = reply.readInt();
  30. reply.recycle();
  31. data.recycle();
  32. return result;
  33. }
查看 mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply,0); 根据标识查找
  1. case START_ACTIVITY_TRANSACTION:
  2. {
  3. data.enforceInterface(IActivityManager.descriptor);
  4. IBinder b = data.readStrongBinder();
  5. IApplicationThread app = ApplicationThreadNative.asInterface(b);
  6. String callingPackage = data.readString();
  7. Intent intent = Intent.CREATOR.createFromParcel(data);
  8. String resolvedType = data.readString();
  9. IBinder resultTo = data.readStrongBinder();
  10. String resultWho = data.readString();
  11. int requestCode = data.readInt();
  12. int startFlags = data.readInt();
  13. ProfilerInfo profilerInfo = data.readInt() != 0
  14. ? ProfilerInfo.CREATOR.createFromParcel(data) : null;
  15. Bundle options = data.readInt() != 0
  16. ? Bundle.CREATOR.createFromParcel(data) : null;
  17. int result = startActivity(app, callingPackage, intent, resolvedType,
  18. resultTo, resultWho, requestCode, startFlags, profilerInfo, options);
  19. reply.writeNoException();
  20. reply.writeInt(result);
  21. return true;
  22. }
点击查找 startActivity
  1. public interface IActivityManager extends IInterface {
  2. public int startActivity(IApplicationThread caller, String callingPackage, Intent intent,
  3. String resolvedType, IBinder resultTo, String resultWho, int requestCode, int flags,
  4. ProfilerInfo profilerInfo, Bundle options) throws RemoteException;
找到具体实现 在ActivityManagerService中
  1. @Override
  2. public final int startActivity(IApplicationThread caller, String callingPackage,
  3. Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
  4. int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
  5. return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
  6. resultWho, requestCode, startFlags, profilerInfo, bOptions,
  7. UserHandle.getCallingUserId());
  8. }
查看startActivityAsUser
  1. @Override
  2. public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
  3. Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
  4. int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
  5. enforceNotIsolatedCaller("startActivity");
  6. userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
  7. userId, false, ALLOW_FULL_ONLY, "startActivity", null);
  8. // TODO: Switch to user app stacks here.
  9. return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
  10. resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
  11. profilerInfo, null, null, bOptions, false, userId, null, null);
  12. }
查看 mActivityStarter.startActivityMayWait
  1. final int startActivityMayWait(IApplicationThread caller, int callingUid,
  2. String callingPackage, Intent intent, String resolvedType,
  3. IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
  4. IBinder resultTo, String resultWho, int requestCode, int startFlags,
  5. ProfilerInfo profilerInfo, IActivityManager.WaitResult outResult, Configuration config,
  6. Bundle bOptions, boolean ignoreTargetSecurity, int userId,
  7. IActivityContainer iContainer, TaskRecord inTask) {
  8. // Refuse possible leaked file descriptors
  9. if (intent != null && intent.hasFileDescriptors()) {
  10. throw new IllegalArgumentException("File descriptors passed in Intent");
  11. }
  12. mSupervisor.mActivityMetricsLogger.notifyActivityLaunching();
  13. boolean componentSpecified = intent.getComponent() != null;
  14. // Save a copy in case ephemeral needs it
  15. final Intent ephemeralIntent = new Intent(intent);
  16. // Don't modify the client's object!
  17. intent = new Intent(intent);
  18. ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId);
  19. if (rInfo == null) {
  20. UserInfo userInfo = mSupervisor.getUserInfo(userId);
  21. if (userInfo != null && userInfo.isManagedProfile()) {
  22. // Special case for managed profiles, if attempting to launch non-cryto aware
  23. // app in a locked managed profile from an unlocked parent allow it to resolve
  24. // as user will be sent via confirm credentials to unlock the profile.
  25. UserManager userManager = UserManager.get(mService.mContext);
  26. boolean profileLockedAndParentUnlockingOrUnlocked = false;
  27. long token = Binder.clearCallingIdentity();
  28. try {
  29. UserInfo parent = userManager.getProfileParent(userId);
  30. profileLockedAndParentUnlockingOrUnlocked = (parent != null)
  31. && userManager.isUserUnlockingOrUnlocked(parent.id)
  32. && !userManager.isUserUnlockingOrUnlocked(userId);
  33. } finally {
  34. Binder.restoreCallingIdentity(token);
  35. }
  36. if (profileLockedAndParentUnlockingOrUnlocked) {
  37. rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId,
  38. PackageManager.MATCH_DIRECT_BOOT_AWARE
  39. | PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
  40. }
  41. }
  42. }
  43. // Collect information about the target of the Intent.
  44. ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);
  45. ActivityOptions options = ActivityOptions.fromBundle(bOptions);
  46. ActivityStackSupervisor.ActivityContainer container =
  47. (ActivityStackSupervisor.ActivityContainer)iContainer;
  48. synchronized (mService) {
  49. if (container != null && container.mParentActivity != null &&
  50. container.mParentActivity.state != RESUMED) {
  51. // Cannot start a child activity if the parent is not resumed.
  52. return ActivityManager.START_CANCELED;
  53. }
  54. final int realCallingPid = Binder.getCallingPid();
  55. final int realCallingUid = Binder.getCallingUid();
  56. int callingPid;
  57. if (callingUid >= 0) {
  58. callingPid = -1;
  59. } else if (caller == null) {
  60. callingPid = realCallingPid;
  61. callingUid = realCallingUid;
  62. } else {
  63. callingPid = callingUid = -1;
  64. }
  65. final ActivityStack stack;
  66. if (container == null || container.mStack.isOnHomeDisplay()) {
  67. stack = mSupervisor.mFocusedStack;
  68. } else {
  69. stack = container.mStack;
  70. }
  71. stack.mConfigWillChange = config != null && mService.mConfiguration.diff(config) != 0;
  72. if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
  73. "Starting activity when config will change = " + stack.mConfigWillChange);
  74. final long origId = Binder.clearCallingIdentity();
  75. if (aInfo != null &&
  76. (aInfo.applicationInfo.privateFlags
  77. & ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0) {
  78. // This may be a heavy-weight process! Check to see if we already
  79. // have another, different heavy-weight process running.
  80. if (aInfo.processName.equals(aInfo.applicationInfo.packageName)) {
  81. final ProcessRecord heavy = mService.mHeavyWeightProcess;
  82. if (heavy != null && (heavy.info.uid != aInfo.applicationInfo.uid
  83. || !heavy.processName.equals(aInfo.processName))) {
  84. int appCallingUid = callingUid;
  85. if (caller != null) {
  86. ProcessRecord callerApp = mService.getRecordForAppLocked(caller);
  87. if (callerApp != null) {
  88. appCallingUid = callerApp.info.uid;
  89. } else {
  90. Slog.w(TAG, "Unable to find app for caller " + caller
  91. + " (pid=" + callingPid + ") when starting: "
  92. + intent.toString());
  93. ActivityOptions.abort(options);
  94. return ActivityManager.START_PERMISSION_DENIED;
  95. }
  96. }
  97. IIntentSender target = mService.getIntentSenderLocked(
  98. ActivityManager.INTENT_SENDER_ACTIVITY, "android",
  99. appCallingUid, userId, null, null, 0, new Intent[] { intent },
  100. new String[] { resolvedType }, PendingIntent.FLAG_CANCEL_CURRENT
  101. | PendingIntent.FLAG_ONE_SHOT, null);
  102. Intent newIntent = new Intent();
  103. if (requestCode >= 0) {
  104. // Caller is requesting a result.
  105. newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_HAS_RESULT, true);
  106. }
  107. newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_INTENT,
  108. new IntentSender(target));
  109. if (heavy.activities.size() > 0) {
  110. ActivityRecord hist = heavy.activities.get(0);
  111. newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_APP,
  112. hist.packageName);
  113. newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_TASK,
  114. hist.task.taskId);
  115. }
  116. newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_NEW_APP,
  117. aInfo.packageName);
  118. newIntent.setFlags(intent.getFlags());
  119. newIntent.setClassName("android",
  120. HeavyWeightSwitcherActivity.class.getName());
  121. intent = newIntent;
  122. resolvedType = null;
  123. caller = null;
  124. callingUid = Binder.getCallingUid();
  125. callingPid = Binder.getCallingPid();
  126. componentSpecified = true;
  127. rInfo = mSupervisor.resolveIntent(intent, null /*resolvedType*/, userId);
  128. aInfo = rInfo != null ? rInfo.activityInfo : null;
  129. if (aInfo != null) {
  130. aInfo = mService.getActivityInfoForUser(aInfo, userId);
  131. }
  132. }
  133. }
  134. }
  135. final ActivityRecord[] outRecord = new ActivityRecord[1];
  136. int res = startActivityLocked(caller, intent, ephemeralIntent, resolvedType,
  137. aInfo, rInfo, voiceSession, voiceInteractor,
  138. resultTo, resultWho, requestCode, callingPid,
  139. callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
  140. options, ignoreTargetSecurity, componentSpecified, outRecord, container,
  141. inTask);
  142. Binder.restoreCallingIdentity(origId);
  143. if (stack.mConfigWillChange) {
  144. // If the caller also wants to switch to a new configuration,
  145. // do so now. This allows a clean switch, as we are waiting
  146. // for the current activity to pause (so we will not destroy
  147. // it), and have not yet started the next activity.
  148. mService.enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
  149. "updateConfiguration()");
  150. stack.mConfigWillChange = false;
  151. if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
  152. "Updating to new configuration after starting activity.");
  153. mService.updateConfigurationLocked(config, null, false);
  154. }
  155. if (outResult != null) {
  156. outResult.result = res;
  157. if (res == ActivityManager.START_SUCCESS) {
  158. mSupervisor.mWaitingActivityLaunched.add(outResult);
  159. do {
  160. try {
  161. mService.wait();
  162. } catch (InterruptedException e) {
  163. }
  164. } while (outResult.result != START_TASK_TO_FRONT
  165. && !outResult.timeout && outResult.who == null);
  166. if (outResult.result == START_TASK_TO_FRONT) {
  167. res = START_TASK_TO_FRONT;
  168. }
  169. }
  170. if (res == START_TASK_TO_FRONT) {
  171. ActivityRecord r = stack.topRunningActivityLocked();
  172. if (r.nowVisible && r.state == RESUMED) {
  173. outResult.timeout = false;
  174. outResult.who = new ComponentName(r.info.packageName, r.info.name);
  175. outResult.totalTime = 0;
  176. outResult.thisTime = 0;
  177. } else {
  178. outResult.thisTime = SystemClock.uptimeMillis();
  179. mSupervisor.mWaitingActivityVisible.add(outResult);
  180. do {
  181. try {
  182. mService.wait();
  183. } catch (InterruptedException e) {
  184. }
  185. } while (!outResult.timeout && outResult.who == null);
  186. }
  187. }
  188. }
  189. final ActivityRecord launchedActivity = mReusedActivity != null
  190. ? mReusedActivity : outRecord[0];
  191. mSupervisor.mActivityMetricsLogger.notifyActivityLaunched(res, launchedActivity);
  192. return res;
  193. }
  194. }
查看 resolveIntent
  1. ResolveInfo resolveIntent(Intent intent, String resolvedType, int userId) {
  2. return resolveIntent(intent, resolvedType, userId, 0);
  3. }
  1. ResolveInfo resolveIntent(Intent intent, String resolvedType, int userId, int flags) {
  2. try {
  3. return AppGlobals.getPackageManager().resolveIntent(intent, resolvedType,
  4. PackageManager.MATCH_DEFAULT_ONLY | flags
  5. | ActivityManagerService.STOCK_PM_FLAGS, userId);
  6. } catch (RemoteException e) {
  7. }
  8. return null;
  9. }
查看 AppGlobals 找到 getPackageManager()方法
  1. public static IPackageManager getPackageManager() {
  2. return ActivityThread.getPackageManager();
  3. }
查看 ActivityThread 中的 getPackageManager()
  1. public static IPackageManager getPackageManager() {
  2. if (sPackageManager != null) {
  3. //Slog.v("PackageManager", "returning cur default = " + sPackageManager);
  4. return sPackageManager;
  5. }
  6. IBinder b = ServiceManager.getService("package");
  7. //Slog.v("PackageManager", "default service binder = " + b);
  8. sPackageManager = IPackageManager.Stub.asInterface(b);
  9. //Slog.v("PackageManager", "default service = " + sPackageManager);
  10. return sPackageManager;
  11. }
查看sPackageManager 是什么
  1. static volatile IPackageManager sPackageManager;
在PackageManagerService中查看resolveIntent
  1. @Override
  2. public ResolveInfo resolveIntent(Intent intent, String resolvedType,
  3. int flags, int userId) {
  4. try {
  5. Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveIntent");
  6. if (!sUserManager.exists(userId)) return null;
  7. flags = updateFlagsForResolve(flags, userId, intent);
  8. enforceCrossUserPermission(Binder.getCallingUid(), userId,
  9. false /*requireFullPermission*/, false /*checkShell*/, "resolve intent");
  10. Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
  11. final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType,
  12. flags, userId);
  13. Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
  14. final ResolveInfo bestChoice =
  15. chooseBestActivity(intent, resolvedType, flags, query, userId);
  16. if (isEphemeralAllowed(intent, query, userId)) {
  17. Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveEphemeral");
  18. final EphemeralResolveInfo ai =
  19. getEphemeralResolveInfo(intent, resolvedType, userId);
  20. if (ai != null) {
  21. if (DEBUG_EPHEMERAL) {
  22. Slog.v(TAG, "Returning an EphemeralResolveInfo");
  23. }
  24. bestChoice.ephemeralInstaller = mEphemeralInstallerInfo;
  25. bestChoice.ephemeralResolveInfo = ai;
  26. }
  27. Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
  28. }
  29. return bestChoice;
  30. } finally {
  31. Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
  32. }
  33. }
查看chooseBestActivity
  1. private ResolveInfo chooseBestActivity(Intent intent, String resolvedType,
  2. int flags, List<ResolveInfo> query, int userId) {
  3. if (query != null) {
  4. final int N = query.size();
  5. if (N == 1) {
  6. return query.get(0);
  7. } else if (N > 1) {
  8. final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
  9. // If there is more than one activity with the same priority,
  10. // then let the user decide between them.
  11. ResolveInfo r0 = query.get(0);
  12. ResolveInfo r1 = query.get(1);
  13. if (DEBUG_INTENT_MATCHING || debug) {
  14. Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs "
  15. + r1.activityInfo.name + "=" + r1.priority);
  16. }
  17. // If the first activity has a higher priority, or a different
  18. // default, then it is always desirable to pick it.
  19. if (r0.priority != r1.priority
  20. || r0.preferredOrder != r1.preferredOrder
  21. || r0.isDefault != r1.isDefault) {
  22. return query.get(0);
  23. }
  24. // If we have saved a preference for a preferred activity for
  25. // this Intent, use that.
  26. ResolveInfo ri = findPreferredActivity(intent, resolvedType,
  27. flags, query, r0.priority, true, false, debug, userId);
  28. if (ri != null) {
  29. return ri;
  30. }
  31. ri = new ResolveInfo(mResolveInfo);
  32. ri.activityInfo = new ActivityInfo(ri.activityInfo);
  33. ri.activityInfo.labelRes = ResolverActivity.getLabelRes(intent.getAction());
  34. // If all of the options come from the same package, show the application's
  35. // label and icon instead of the generic resolver's.
  36. // Some calls like Intent.resolveActivityInfo query the ResolveInfo from here
  37. // and then throw away the ResolveInfo itself, meaning that the caller loses
  38. // the resolvePackageName. Therefore the activityInfo.labelRes above provides
  39. // a fallback for this case; we only set the target package's resources on
  40. // the ResolveInfo, not the ActivityInfo.
  41. final String intentPackage = intent.getPackage();
  42. if (!TextUtils.isEmpty(intentPackage) && allHavePackage(query, intentPackage)) {
  43. final ApplicationInfo appi = query.get(0).activityInfo.applicationInfo;
  44. ri.resolvePackageName = intentPackage;
  45. if (userNeedsBadging(userId)) {
  46. ri.noResourceId = true;
  47. } else {
  48. ri.icon = appi.icon;
  49. }
  50. ri.iconResourceId = appi.icon;
  51. ri.labelRes = appi.labelRes;
  52. }
  53. ri.activityInfo.applicationInfo = new ApplicationInfo(
  54. ri.activityInfo.applicationInfo);
  55. if (userId != 0) {
  56. ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId,
  57. UserHandle.getAppId(ri.activityInfo.applicationInfo.uid));
  58. }
  59. // Make sure that the resolver is displayable in car mode
  60. if (ri.activityInfo.metaData == null) ri.activityInfo.metaData = new Bundle();
  61. ri.activityInfo.metaData.putBoolean(Intent.METADATA_DOCK_HOME, true);
  62. return ri;
  63. }
  64. }
  65. return null;
  66. }
查找findPreferredActivity
  1. ResolveInfo findPreferredActivity(Intent intent, String resolvedType, int flags,
  2. List<ResolveInfo> query, int priority, boolean always,
  3. boolean removeMatches, boolean debug, int userId) {
  4. if (!sUserManager.exists(userId)) return null;
  5. flags = updateFlagsForResolve(flags, userId, intent);
  6. // writer
  7. synchronized (mPackages) {
  8. if (intent.getSelector() != null) {
  9. intent = intent.getSelector();
  10. }
  11. if (DEBUG_PREFERRED) intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION);
  12. // Try to find a matching persistent preferred activity.
  13. ResolveInfo pri = findPersistentPreferredActivityLP(intent, resolvedType, flags, query,
  14. debug, userId);
  15. // If a persistent preferred activity matched, use it.
  16. if (pri != null) {
  17. return pri;
  18. }
  19. PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
  20. // Get the list of preferred activities that handle the intent
  21. if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities...");
  22. List<PreferredActivity> prefs = pir != null
  23. ? pir.queryIntent(intent, resolvedType,
  24. (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId)
  25. : null;
  26. if (prefs != null && prefs.size() > 0) {
  27. boolean changed = false;
  28. try {
  29. // First figure out how good the original match set is.
  30. // We will only allow preferred activities that came
  31. // from the same match quality.
  32. int match = 0;
  33. if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match...");
  34. final int N = query.size();
  35. for (int j=0; j<N; j++) {
  36. final ResolveInfo ri = query.get(j);
  37. if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo
  38. + ": 0x" + Integer.toHexString(match));
  39. if (ri.match > match) {
  40. match = ri.match;
  41. }
  42. }
  43. if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x"
  44. + Integer.toHexString(match));
  45. match &= IntentFilter.MATCH_CATEGORY_MASK;
  46. final int M = prefs.size();
  47. for (int i=0; i<M; i++) {
  48. final PreferredActivity pa = prefs.get(i);
  49. if (DEBUG_PREFERRED || debug) {
  50. Slog.v(TAG, "Checking PreferredActivity ds="
  51. + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>")
  52. + "\n component=" + pa.mPref.mComponent);
  53. pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " ");
  54. }
  55. if (pa.mPref.mMatch != match) {
  56. if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match "
  57. + Integer.toHexString(pa.mPref.mMatch));
  58. continue;
  59. }
  60. // If it's not an "always" type preferred activity and that's what we're
  61. // looking for, skip it.
  62. if (always && !pa.mPref.mAlways) {
  63. if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry");
  64. continue;
  65. }
  66. final ActivityInfo ai = getActivityInfo(
  67. pa.mPref.mComponent, flags | MATCH_DISABLED_COMPONENTS
  68. | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
  69. userId);
  70. if (DEBUG_PREFERRED || debug) {
  71. Slog.v(TAG, "Found preferred activity:");
  72. if (ai != null) {
  73. ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), " ");
  74. } else {
  75. Slog.v(TAG, " null");
  76. }
  77. }
  78. if (ai == null) {
  79. // This previously registered preferred activity
  80. // component is no longer known. Most likely an update
  81. // to the app was installed and in the new version this
  82. // component no longer exists. Clean it up by removing
  83. // it from the preferred activities list, and skip it.
  84. Slog.w(TAG, "Removing dangling preferred activity: "
  85. + pa.mPref.mComponent);
  86. pir.removeFilter(pa);
  87. changed = true;
  88. continue;
  89. }
  90. for (int j=0; j<N; j++) {
  91. final ResolveInfo ri = query.get(j);
  92. if (!ri.activityInfo.applicationInfo.packageName
  93. .equals(ai.applicationInfo.packageName)) {
  94. continue;
  95. }
  96. if (!ri.activityInfo.name.equals(ai.name)) {
  97. continue;
  98. }
  99. if (removeMatches) {
  100. pir.removeFilter(pa);
  101. changed = true;
  102. if (DEBUG_PREFERRED) {
  103. Slog.v(TAG, "Removing match " + pa.mPref.mComponent);
  104. }
  105. break;
  106. }
  107. // Okay we found a previously set preferred or last chosen app.
  108. // If the result set is different from when this
  109. // was created, we need to clear it and re-ask the
  110. // user their preference, if we're looking for an "always" type entry.
  111. if (always && !pa.mPref.sameSet(query)) {
  112. Slog.i(TAG, "Result set changed, dropping preferred activity for "
  113. + intent + " type " + resolvedType);
  114. if (DEBUG_PREFERRED) {
  115. Slog.v(TAG, "Removing preferred activity since set changed "
  116. + pa.mPref.mComponent);
  117. }
  118. pir.removeFilter(pa);
  119. // Re-add the filter as a "last chosen" entry (!always)
  120. PreferredActivity lastChosen = new PreferredActivity(
  121. pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false);
  122. pir.addFilter(lastChosen);
  123. changed = true;
  124. return null;
  125. }
  126. // Yay! Either the set matched or we're looking for the last chosen
  127. if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: "
  128. + ri.activityInfo.packageName + "/" + ri.activityInfo.name);
  129. return ri;
  130. }
  131. }
  132. } finally {
  133. if (changed) {
  134. if (DEBUG_PREFERRED) {
  135. Slog.v(TAG, "Preferred activity bookkeeping changed; writing restrictions");
  136. }
  137. scheduleWritePackageRestrictionsLocked(userId);
  138. }
  139. }
  140. }
  141. }
  142. if (DEBUG_PREFERRED || debug) Slog.v(TAG, "No preferred activity to return");
  143. return null;
  144. }






总结:
IActivityManager具体实现 ActivityManagerService
ApplicationThread在ActivityThread中
ActivityStarter这个类收集所有的逻辑,以确定如何将意图和标志转换为一个活动和相关的任务和堆栈。
ActivityStackSupervisor   activity任务栈管理
IPackageManager 的实现是PackageManagerService