当前位置:   article > 正文

Android startActivity流程

android startactivity

1.常规调用

startActivity(new Intent(this,MainActivity.class));

进入Activity的startActivity方法

  1. /**
  2. * Same as {@link #startActivity(Intent, Bundle)} with no options
  3. * specified.
  4. *
  5. * @param intent The intent to start.
  6. *
  7. * @throws android.content.ActivityNotFoundException
  8. *
  9. * @see #startActivity(Intent, Bundle)
  10. * @see #startActivityForResult
  11. */
  12. @Override
  13. public void startActivity(Intent intent) {
  14. this.startActivity(intent, null);
  15. }

 进入Activity的startActivityForResult方法

  1. /**
  2. * Launch a new activity. You will not receive any information about when
  3. * the activity exits. This implementation overrides the base version,
  4. * providing information about
  5. * the activity performing the launch. Because of this additional
  6. * information, the {@link Intent#FLAG_ACTIVITY_NEW_TASK} launch flag is not
  7. * required; if not specified, the new activity will be added to the
  8. * task of the caller.
  9. *
  10. * <p>This method throws {@link android.content.ActivityNotFoundException}
  11. * if there was no Activity found to run the given Intent.
  12. *
  13. * @param intent The intent to start.
  14. * @param options Additional options for how the Activity should be started.
  15. * See {@link android.content.Context#startActivity(Intent, Bundle)}
  16. * Context.startActivity(Intent, Bundle)} for more details.
  17. *
  18. * @throws android.content.ActivityNotFoundException
  19. *
  20. * @see #startActivity(Intent)
  21. * @see #startActivityForResult
  22. */
  23. @Override
  24. public void startActivity(Intent intent, @Nullable Bundle options) {
  25. getAutofillClientController().onStartActivity(intent, mIntent);
  26. if (options != null) {
  27. startActivityForResult(intent, -1, options);
  28. } else {
  29. // Note we want to go through this call for compatibility with
  30. // applications that may have overridden the method.
  31. startActivityForResult(intent, -1);
  32. }
  33. }
  1. /**
  2. * Same as calling {@link #startActivityForResult(Intent, int, Bundle)}
  3. * with no options.
  4. *
  5. * @param intent The intent to start.
  6. * @param requestCode If >= 0, this code will be returned in
  7. * onActivityResult() when the activity exits.
  8. *
  9. * @throws android.content.ActivityNotFoundException
  10. *
  11. * @see #startActivity
  12. */
  13. public void startActivityForResult(@RequiresPermission Intent intent, int requestCode) {
  14. startActivityForResult(intent, requestCode, null);
  15. }
  1. /**
  2. * Launch an activity for which you would like a result when it finished.
  3. * When this activity exits, your
  4. * onActivityResult() method will be called with the given requestCode.
  5. * Using a negative requestCode is the same as calling
  6. * {@link #startActivity} (the activity is not launched as a sub-activity).
  7. *
  8. * <p>Note that this method should only be used with Intent protocols
  9. * that are defined to return a result. In other protocols (such as
  10. * {@link Intent#ACTION_MAIN} or {@link Intent#ACTION_VIEW}), you may
  11. * not get the result when you expect. For example, if the activity you
  12. * are launching uses {@link Intent#FLAG_ACTIVITY_NEW_TASK}, it will not
  13. * run in your task and thus you will immediately receive a cancel result.
  14. *
  15. * <p>As a special case, if you call startActivityForResult() with a requestCode
  16. * >= 0 during the initial onCreate(Bundle savedInstanceState)/onResume() of your
  17. * activity, then your window will not be displayed until a result is
  18. * returned back from the started activity. This is to avoid visible
  19. * flickering when redirecting to another activity.
  20. *
  21. * <p>This method throws {@link android.content.ActivityNotFoundException}
  22. * if there was no Activity found to run the given Intent.
  23. *
  24. * @param intent The intent to start.
  25. * @param requestCode If >= 0, this code will be returned in
  26. * onActivityResult() when the activity exits.
  27. * @param options Additional options for how the Activity should be started.
  28. * See {@link android.content.Context#startActivity(Intent, Bundle)}
  29. * Context.startActivity(Intent, Bundle)} for more details.
  30. *
  31. * @throws android.content.ActivityNotFoundException
  32. *
  33. * @see #startActivity
  34. */
  35. public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
  36. @Nullable Bundle options) {
  37. if (mParent == null) {
  38. options = transferSpringboardActivityOptions(options);
  39. Instrumentation.ActivityResult ar =
  40. mInstrumentation.execStartActivity(
  41. this, mMainThread.getApplicationThread(), mToken, this,
  42. intent, requestCode, options);
  43. if (ar != null) {
  44. mMainThread.sendActivityResult(
  45. mToken, mEmbeddedID, requestCode, ar.getResultCode(),
  46. ar.getResultData());
  47. }
  48. if (requestCode >= 0) {
  49. // If this start is requesting a result, we can avoid making
  50. // the activity visible until the result is received. Setting
  51. // this code during onCreate(Bundle savedInstanceState) or onResume() will keep the
  52. // activity hidden during this time, to avoid flickering.
  53. // This can only be done when a result is requested because
  54. // that guarantees we will get information back when the
  55. // activity is finished, no matter what happens to it.
  56. mStartedActivity = true;
  57. }
  58. cancelInputsAndStartExitTransition(options);
  59. // TODO Consider clearing/flushing other event sources and events for child windows.
  60. } else {
  61. if (options != null) {
  62. mParent.startActivityFromChild(this, intent, requestCode, options);
  63. } else {
  64. // Note we want to go through this method for compatibility with
  65. // existing applications that may have overridden it.
  66. mParent.startActivityFromChild(this, intent, requestCode);
  67. }
  68. }
  69. }

如果父activity不存在就调用

mInstrumentation.execStartActivity

如果父activity存在就调用

mParent.startActivityFromChild

mInstrumentation.execStartActivity会调用ATMS的

ActivityTaskManager.getService().startActivity
  1. /**
  2. * Execute a startActivity call made by the application. The default
  3. * implementation takes care of updating any active {@link ActivityMonitor}
  4. * objects and dispatches this call to the system activity manager; you can
  5. * override this to watch for the application to start an activity, and
  6. * modify what happens when it does.
  7. *
  8. * <p>This method returns an {@link ActivityResult} object, which you can
  9. * use when intercepting application calls to avoid performing the start
  10. * activity action but still return the result the application is
  11. * expecting. To do this, override this method to catch the call to start
  12. * activity so that it returns a new ActivityResult containing the results
  13. * you would like the application to see, and don't call up to the super
  14. * class. Note that an application is only expecting a result if
  15. * <var>requestCode</var> is &gt;= 0.
  16. *
  17. * <p>This method throws {@link android.content.ActivityNotFoundException}
  18. * if there was no Activity found to run the given Intent.
  19. *
  20. * @param who The Context from which the activity is being started.
  21. * @param contextThread The main thread of the Context from which the activity
  22. * is being started.
  23. * @param token Internal token identifying to the system who is starting
  24. * the activity; may be null.
  25. * @param target Which activity is performing the start (and thus receiving
  26. * any result); may be null if this call is not being made
  27. * from an activity.
  28. * @param intent The actual Intent to start.
  29. * @param requestCode Identifier for this request's result; less than zero
  30. * if the caller is not expecting a result.
  31. * @param options Addition options.
  32. *
  33. * @return To force the return of a particular result, return an
  34. * ActivityResult object containing the desired data; otherwise
  35. * return null. The default implementation always returns null.
  36. *
  37. * @throws android.content.ActivityNotFoundException
  38. *
  39. * @see Activity#startActivity(Intent)
  40. * @see Activity#startActivityForResult(Intent, int)
  41. *
  42. * {@hide}
  43. */
  44. @UnsupportedAppUsage
  45. public ActivityResult execStartActivity(
  46. Context who, IBinder contextThread, IBinder token, Activity target,
  47. Intent intent, int requestCode, Bundle options) {
  48. IApplicationThread whoThread = (IApplicationThread) contextThread;
  49. Uri referrer = target != null ? target.onProvideReferrer() : null;
  50. if (referrer != null) {
  51. intent.putExtra(Intent.EXTRA_REFERRER, referrer);
  52. }
  53. if (mActivityMonitors != null) {
  54. synchronized (mSync) {
  55. final int N = mActivityMonitors.size();
  56. for (int i=0; i<N; i++) {
  57. final ActivityMonitor am = mActivityMonitors.get(i);
  58. ActivityResult result = null;
  59. if (am.ignoreMatchingSpecificIntents()) {
  60. if (options == null) {
  61. options = ActivityOptions.makeBasic().toBundle();
  62. }
  63. result = am.onStartActivity(who, intent, options);
  64. }
  65. if (result != null) {
  66. am.mHits++;
  67. return result;
  68. } else if (am.match(who, null, intent)) {
  69. am.mHits++;
  70. if (am.isBlocking()) {
  71. return requestCode >= 0 ? am.getResult() : null;
  72. }
  73. break;
  74. }
  75. }
  76. }
  77. }
  78. try {
  79. intent.migrateExtraStreamToClipData(who);
  80. intent.prepareToLeaveProcess(who);
  81. int result = ActivityTaskManager.getService().startActivity(whoThread,
  82. who.getOpPackageName(), who.getAttributionTag(), intent,
  83. intent.resolveTypeIfNeeded(who.getContentResolver()), token,
  84. target != null ? target.mEmbeddedID : null, requestCode, 0, null, options);
  85. checkStartActivityResult(result, intent);
  86. } catch (RemoteException e) {
  87. throw new RuntimeException("Failure from system", e);
  88. }
  89. return null;
  90. }

mParent.startActivityFromChild内部调用的也是mInstrumentation.execStartActivity

  1. /**
  2. * This is called when a child activity of this one calls its
  3. * {@link #startActivity} or {@link #startActivityForResult} method.
  4. *
  5. * <p>This method throws {@link android.content.ActivityNotFoundException}
  6. * if there was no Activity found to run the given Intent.
  7. *
  8. * @param child The activity making the call.
  9. * @param intent The intent to start.
  10. * @param requestCode Reply request code. < 0 if reply is not requested.
  11. * @param options Additional options for how the Activity should be started.
  12. * See {@link android.content.Context#startActivity(Intent, Bundle)}
  13. * Context.startActivity(Intent, Bundle)} for more details.
  14. *
  15. * @throws android.content.ActivityNotFoundException
  16. *
  17. * @see #startActivity
  18. * @see #startActivityForResult
  19. * @deprecated Use {@code androidx.fragment.app.FragmentActivity#startActivityFromFragment(
  20. * androidx.fragment.app.Fragment,Intent,int,Bundle)}
  21. */
  22. @Deprecated
  23. public void startActivityFromChild(@NonNull Activity child, @RequiresPermission Intent intent,
  24. int requestCode, @Nullable Bundle options) {
  25. options = transferSpringboardActivityOptions(options);
  26. Instrumentation.ActivityResult ar =
  27. mInstrumentation.execStartActivity(
  28. this, mMainThread.getApplicationThread(), mToken, child,
  29. intent, requestCode, options);
  30. if (ar != null) {
  31. mMainThread.sendActivityResult(
  32. mToken, child.mEmbeddedID, requestCode,
  33. ar.getResultCode(), ar.getResultData());
  34. }
  35. cancelInputsAndStartExitTransition(options);
  36. }

framework/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java

startActivity调用startActivityAsUser

  1. @Override
  2. public final int startActivity(IApplicationThread caller, String callingPackage,
  3. String callingFeatureId, Intent intent, String resolvedType, IBinder resultTo,
  4. String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo,
  5. Bundle bOptions) {
  6. return startActivityAsUser(caller, callingPackage, callingFeatureId, intent, resolvedType,
  7. resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions,
  8. UserHandle.getCallingUserId());
  9. }

 startActivityAsUser

  1. @Override
  2. public int startActivityAsUser(IApplicationThread caller, String callingPackage,
  3. String callingFeatureId, Intent intent, String resolvedType, IBinder resultTo,
  4. String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo,
  5. Bundle bOptions, int userId) {
  6. return startActivityAsUser(caller, callingPackage, callingFeatureId, intent, resolvedType,
  7. resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,
  8. true /*validateIncomingUser*/);
  9. }
  1. private int startActivityAsUser(IApplicationThread caller, String callingPackage,
  2. @Nullable String callingFeatureId, Intent intent, String resolvedType,
  3. IBinder resultTo, String resultWho, int requestCode, int startFlags,
  4. ProfilerInfo profilerInfo, Bundle bOptions, int userId, boolean validateIncomingUser) {
  5. assertPackageMatchesCallingUid(callingPackage);
  6. enforceNotIsolatedCaller("startActivityAsUser");
  7. userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
  8. Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
  9. // TODO: Switch to user app stacks here.
  10. return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
  11. .setCaller(caller)
  12. .setCallingPackage(callingPackage)
  13. .setCallingFeatureId(callingFeatureId)
  14. .setResolvedType(resolvedType)
  15. .setResultTo(resultTo)
  16. .setResultWho(resultWho)
  17. .setRequestCode(requestCode)
  18. .setStartFlags(startFlags)
  19. .setProfilerInfo(profilerInfo)
  20. .setActivityOptions(bOptions)
  21. .setUserId(userId)
  22. .execute();
  23. }

获取:getActivityStartController().obtainStarter

  1. ActivityStartController getActivityStartController() {
  2. return mActivityStartController;
  3. }
  1. ActivityStarter obtainStarter(Intent intent, String reason) {
  2. return mFactory.obtain().setIntent(intent).setReason(reason);
  3. }
  1. /**
  2. * Resolve necessary information according the request parameters provided earlier, and execute
  3. * the request which begin the journey of starting an activity.
  4. * @return The starter result.
  5. */
  6. int execute() {
  7. try {
  8. // Refuse possible leaked file descriptors
  9. if (mRequest.intent != null && mRequest.intent.hasFileDescriptors()) {
  10. throw new IllegalArgumentException("File descriptors passed in Intent");
  11. }
  12. final LaunchingState launchingState;
  13. synchronized (mService.mGlobalLock) {
  14. final ActivityRecord caller = ActivityRecord.forTokenLocked(mRequest.resultTo);
  15. final int callingUid = mRequest.realCallingUid == Request.DEFAULT_REAL_CALLING_UID
  16. ? Binder.getCallingUid() : mRequest.realCallingUid;
  17. launchingState = mSupervisor.getActivityMetricsLogger().notifyActivityLaunching(
  18. mRequest.intent, caller, callingUid);
  19. }
  20. // If the caller hasn't already resolved the activity, we're willing
  21. // to do so here. If the caller is already holding the WM lock here,
  22. // and we need to check dynamic Uri permissions, then we're forced
  23. // to assume those permissions are denied to avoid deadlocking.
  24. if (mRequest.activityInfo == null) {
  25. mRequest.resolveActivity(mSupervisor);
  26. }
  27. // Add checkpoint for this shutdown or reboot attempt, so we can record the original
  28. // intent action and package name.
  29. if (mRequest.intent != null) {
  30. String intentAction = mRequest.intent.getAction();
  31. String callingPackage = mRequest.callingPackage;
  32. if (intentAction != null && callingPackage != null
  33. && (Intent.ACTION_REQUEST_SHUTDOWN.equals(intentAction)
  34. || Intent.ACTION_SHUTDOWN.equals(intentAction)
  35. || Intent.ACTION_REBOOT.equals(intentAction))) {
  36. ShutdownCheckPoints.recordCheckPoint(intentAction, callingPackage, null);
  37. }
  38. }
  39. int res;
  40. synchronized (mService.mGlobalLock) {
  41. final boolean globalConfigWillChange = mRequest.globalConfig != null
  42. && mService.getGlobalConfiguration().diff(mRequest.globalConfig) != 0;
  43. final Task rootTask = mRootWindowContainer.getTopDisplayFocusedRootTask();
  44. if (rootTask != null) {
  45. rootTask.mConfigWillChange = globalConfigWillChange;
  46. }
  47. ProtoLog.v(WM_DEBUG_CONFIGURATION, "Starting activity when config "
  48. + "will change = %b", globalConfigWillChange);
  49. final long origId = Binder.clearCallingIdentity();
  50. res = resolveToHeavyWeightSwitcherIfNeeded();
  51. if (res != START_SUCCESS) {
  52. return res;
  53. }
  54. res = executeRequest(mRequest);
  55. Binder.restoreCallingIdentity(origId);
  56. if (globalConfigWillChange) {
  57. // If the caller also wants to switch to a new configuration, do so now.
  58. // This allows a clean switch, as we are waiting for the current activity
  59. // to pause (so we will not destroy it), and have not yet started the
  60. // next activity.
  61. mService.mAmInternal.enforceCallingPermission(
  62. android.Manifest.permission.CHANGE_CONFIGURATION,
  63. "updateConfiguration()");
  64. if (rootTask != null) {
  65. rootTask.mConfigWillChange = false;
  66. }
  67. ProtoLog.v(WM_DEBUG_CONFIGURATION,
  68. "Updating to new configuration after starting activity.");
  69. mService.updateConfigurationLocked(mRequest.globalConfig, null, false);
  70. }
  71. // The original options may have additional info about metrics. The mOptions is not
  72. // used here because it may be cleared in setTargetRootTaskIfNeeded.
  73. final ActivityOptions originalOptions = mRequest.activityOptions != null
  74. ? mRequest.activityOptions.getOriginalOptions() : null;
  75. // If the new record is the one that started, a new activity has created.
  76. final boolean newActivityCreated = mStartActivity == mLastStartActivityRecord;
  77. // Notify ActivityMetricsLogger that the activity has launched.
  78. // ActivityMetricsLogger will then wait for the windows to be drawn and populate
  79. // WaitResult.
  80. mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(launchingState, res,
  81. newActivityCreated, mLastStartActivityRecord, originalOptions);
  82. if (mRequest.waitResult != null) {
  83. mRequest.waitResult.result = res;
  84. res = waitResultIfNeeded(mRequest.waitResult, mLastStartActivityRecord,
  85. launchingState);
  86. }
  87. return getExternalResult(res);
  88. }
  89. } finally {
  90. onExecutionComplete();
  91. }
  92. }

Android | Activity 启动流程分析 - 掘金 (juejin.cn)

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/685765
推荐阅读
相关标签
  

闽ICP备14008679号