赞
踩
startActivity(new Intent(this,MainActivity.class));
进入Activity的startActivity方法
- /**
- * Same as {@link #startActivity(Intent, Bundle)} with no options
- * specified.
- *
- * @param intent The intent to start.
- *
- * @throws android.content.ActivityNotFoundException
- *
- * @see #startActivity(Intent, Bundle)
- * @see #startActivityForResult
- */
- @Override
- public void startActivity(Intent intent) {
- this.startActivity(intent, null);
- }
进入Activity的startActivityForResult方法
- /**
- * Launch a new activity. You will not receive any information about when
- * the activity exits. This implementation overrides the base version,
- * providing information about
- * the activity performing the launch. Because of this additional
- * information, the {@link Intent#FLAG_ACTIVITY_NEW_TASK} launch flag is not
- * required; if not specified, the new activity will be added to the
- * task of the caller.
- *
- * <p>This method throws {@link android.content.ActivityNotFoundException}
- * if there was no Activity found to run the given Intent.
- *
- * @param intent The intent to start.
- * @param options Additional options for how the Activity should be started.
- * See {@link android.content.Context#startActivity(Intent, Bundle)}
- * Context.startActivity(Intent, Bundle)} for more details.
- *
- * @throws android.content.ActivityNotFoundException
- *
- * @see #startActivity(Intent)
- * @see #startActivityForResult
- */
- @Override
- public void startActivity(Intent intent, @Nullable Bundle options) {
- getAutofillClientController().onStartActivity(intent, mIntent);
- 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);
- }
- }
- /**
- * Same as calling {@link #startActivityForResult(Intent, int, Bundle)}
- * with no options.
- *
- * @param intent The intent to start.
- * @param requestCode If >= 0, this code will be returned in
- * onActivityResult() when the activity exits.
- *
- * @throws android.content.ActivityNotFoundException
- *
- * @see #startActivity
- */
- public void startActivityForResult(@RequiresPermission Intent intent, int requestCode) {
- startActivityForResult(intent, requestCode, null);
- }
- /**
- * Launch an activity for which you would like a result when it finished.
- * When this activity exits, your
- * onActivityResult() method will be called with the given requestCode.
- * Using a negative requestCode is the same as calling
- * {@link #startActivity} (the activity is not launched as a sub-activity).
- *
- * <p>Note that this method should only be used with Intent protocols
- * that are defined to return a result. In other protocols (such as
- * {@link Intent#ACTION_MAIN} or {@link Intent#ACTION_VIEW}), you may
- * not get the result when you expect. For example, if the activity you
- * are launching uses {@link Intent#FLAG_ACTIVITY_NEW_TASK}, it will not
- * run in your task and thus you will immediately receive a cancel result.
- *
- * <p>As a special case, if you call startActivityForResult() with a requestCode
- * >= 0 during the initial onCreate(Bundle savedInstanceState)/onResume() of your
- * activity, then your window will not be displayed until a result is
- * returned back from the started activity. This is to avoid visible
- * flickering when redirecting to another activity.
- *
- * <p>This method throws {@link android.content.ActivityNotFoundException}
- * if there was no Activity found to run the given Intent.
- *
- * @param intent The intent to start.
- * @param requestCode If >= 0, this code will be returned in
- * onActivityResult() when the activity exits.
- * @param options Additional options for how the Activity should be started.
- * See {@link android.content.Context#startActivity(Intent, Bundle)}
- * Context.startActivity(Intent, Bundle)} for more details.
- *
- * @throws android.content.ActivityNotFoundException
- *
- * @see #startActivity
- */
- public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
- @Nullable Bundle options) {
- if (mParent == null) {
- options = transferSpringboardActivityOptions(options);
- Instrumentation.ActivityResult ar =
- mInstrumentation.execStartActivity(
- this, mMainThread.getApplicationThread(), mToken, this,
- intent, requestCode, options);
- if (ar != null) {
- mMainThread.sendActivityResult(
- mToken, mEmbeddedID, requestCode, ar.getResultCode(),
- ar.getResultData());
- }
- if (requestCode >= 0) {
- // If this start is requesting a result, we can avoid making
- // the activity visible until the result is received. Setting
- // this code during onCreate(Bundle savedInstanceState) or onResume() will keep the
- // activity hidden during this time, to avoid flickering.
- // This can only be done when a result is requested because
- // that guarantees we will get information back when the
- // activity is finished, no matter what happens to it.
- mStartedActivity = true;
- }
-
- cancelInputsAndStartExitTransition(options);
- // TODO Consider clearing/flushing other event sources and events for child windows.
- } else {
- if (options != null) {
- mParent.startActivityFromChild(this, intent, requestCode, options);
- } else {
- // Note we want to go through this method for compatibility with
- // existing applications that may have overridden it.
- mParent.startActivityFromChild(this, intent, requestCode);
- }
- }
- }
如果父activity不存在就调用
mInstrumentation.execStartActivity
如果父activity存在就调用
mParent.startActivityFromChild
mInstrumentation.execStartActivity会调用ATMS的
ActivityTaskManager.getService().startActivity
- /**
- * Execute a startActivity call made by the application. The default
- * implementation takes care of updating any active {@link ActivityMonitor}
- * objects and dispatches this call to the system activity manager; you can
- * override this to watch for the application to start an activity, and
- * modify what happens when it does.
- *
- * <p>This method returns an {@link ActivityResult} object, which you can
- * use when intercepting application calls to avoid performing the start
- * activity action but still return the result the application is
- * expecting. To do this, override this method to catch the call to start
- * activity so that it returns a new ActivityResult containing the results
- * you would like the application to see, and don't call up to the super
- * class. Note that an application is only expecting a result if
- * <var>requestCode</var> is >= 0.
- *
- * <p>This method throws {@link android.content.ActivityNotFoundException}
- * if there was no Activity found to run the given Intent.
- *
- * @param who The Context from which the activity is being started.
- * @param contextThread The main thread of the Context from which the activity
- * is being started.
- * @param token Internal token identifying to the system who is starting
- * the activity; may be null.
- * @param target Which activity is performing the start (and thus receiving
- * any result); may be null if this call is not being made
- * from an activity.
- * @param intent The actual Intent to start.
- * @param requestCode Identifier for this request's result; less than zero
- * if the caller is not expecting a result.
- * @param options Addition options.
- *
- * @return To force the return of a particular result, return an
- * ActivityResult object containing the desired data; otherwise
- * return null. The default implementation always returns null.
- *
- * @throws android.content.ActivityNotFoundException
- *
- * @see Activity#startActivity(Intent)
- * @see Activity#startActivityForResult(Intent, int)
- *
- * {@hide}
- */
- @UnsupportedAppUsage
- public ActivityResult execStartActivity(
- Context who, IBinder contextThread, IBinder token, Activity target,
- Intent intent, int requestCode, Bundle options) {
- IApplicationThread whoThread = (IApplicationThread) contextThread;
- Uri referrer = target != null ? target.onProvideReferrer() : null;
- if (referrer != null) {
- intent.putExtra(Intent.EXTRA_REFERRER, referrer);
- }
- if (mActivityMonitors != null) {
- synchronized (mSync) {
- final int N = mActivityMonitors.size();
- for (int i=0; i<N; i++) {
- final ActivityMonitor am = mActivityMonitors.get(i);
- ActivityResult result = null;
- if (am.ignoreMatchingSpecificIntents()) {
- if (options == null) {
- options = ActivityOptions.makeBasic().toBundle();
- }
- result = am.onStartActivity(who, intent, options);
- }
- if (result != null) {
- am.mHits++;
- return result;
- } else if (am.match(who, null, intent)) {
- am.mHits++;
- if (am.isBlocking()) {
- return requestCode >= 0 ? am.getResult() : null;
- }
- break;
- }
- }
- }
- }
- try {
- intent.migrateExtraStreamToClipData(who);
- intent.prepareToLeaveProcess(who);
- int result = ActivityTaskManager.getService().startActivity(whoThread,
- who.getOpPackageName(), who.getAttributionTag(), intent,
- intent.resolveTypeIfNeeded(who.getContentResolver()), token,
- target != null ? target.mEmbeddedID : null, requestCode, 0, null, options);
- checkStartActivityResult(result, intent);
- } catch (RemoteException e) {
- throw new RuntimeException("Failure from system", e);
- }
- return null;
- }
mParent.startActivityFromChild内部调用的也是mInstrumentation.execStartActivity
- /**
- * This is called when a child activity of this one calls its
- * {@link #startActivity} or {@link #startActivityForResult} method.
- *
- * <p>This method throws {@link android.content.ActivityNotFoundException}
- * if there was no Activity found to run the given Intent.
- *
- * @param child The activity making the call.
- * @param intent The intent to start.
- * @param requestCode Reply request code. < 0 if reply is not requested.
- * @param options Additional options for how the Activity should be started.
- * See {@link android.content.Context#startActivity(Intent, Bundle)}
- * Context.startActivity(Intent, Bundle)} for more details.
- *
- * @throws android.content.ActivityNotFoundException
- *
- * @see #startActivity
- * @see #startActivityForResult
- * @deprecated Use {@code androidx.fragment.app.FragmentActivity#startActivityFromFragment(
- * androidx.fragment.app.Fragment,Intent,int,Bundle)}
- */
- @Deprecated
- public void startActivityFromChild(@NonNull Activity child, @RequiresPermission Intent intent,
- int requestCode, @Nullable Bundle options) {
- options = transferSpringboardActivityOptions(options);
- Instrumentation.ActivityResult ar =
- mInstrumentation.execStartActivity(
- this, mMainThread.getApplicationThread(), mToken, child,
- intent, requestCode, options);
- if (ar != null) {
- mMainThread.sendActivityResult(
- mToken, child.mEmbeddedID, requestCode,
- ar.getResultCode(), ar.getResultData());
- }
- cancelInputsAndStartExitTransition(options);
- }
framework/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
startActivity调用startActivityAsUser
- @Override
- public final int startActivity(IApplicationThread caller, String callingPackage,
- String callingFeatureId, Intent intent, String resolvedType, IBinder resultTo,
- String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo,
- Bundle bOptions) {
- return startActivityAsUser(caller, callingPackage, callingFeatureId, intent, resolvedType,
- resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions,
- UserHandle.getCallingUserId());
- }
startActivityAsUser
- @Override
- public int startActivityAsUser(IApplicationThread caller, String callingPackage,
- String callingFeatureId, Intent intent, String resolvedType, IBinder resultTo,
- String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo,
- Bundle bOptions, int userId) {
- return startActivityAsUser(caller, callingPackage, callingFeatureId, intent, resolvedType,
- resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,
- true /*validateIncomingUser*/);
- }
- private int startActivityAsUser(IApplicationThread caller, String callingPackage,
- @Nullable String callingFeatureId, Intent intent, String resolvedType,
- IBinder resultTo, String resultWho, int requestCode, int startFlags,
- ProfilerInfo profilerInfo, Bundle bOptions, int userId, boolean validateIncomingUser) {
- assertPackageMatchesCallingUid(callingPackage);
- enforceNotIsolatedCaller("startActivityAsUser");
-
- userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
- Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
-
- // TODO: Switch to user app stacks here.
- return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
- .setCaller(caller)
- .setCallingPackage(callingPackage)
- .setCallingFeatureId(callingFeatureId)
- .setResolvedType(resolvedType)
- .setResultTo(resultTo)
- .setResultWho(resultWho)
- .setRequestCode(requestCode)
- .setStartFlags(startFlags)
- .setProfilerInfo(profilerInfo)
- .setActivityOptions(bOptions)
- .setUserId(userId)
- .execute();
-
- }
获取:getActivityStartController().obtainStarter
- ActivityStartController getActivityStartController() {
- return mActivityStartController;
- }
- ActivityStarter obtainStarter(Intent intent, String reason) {
- return mFactory.obtain().setIntent(intent).setReason(reason);
- }
-
- /**
- * Resolve necessary information according the request parameters provided earlier, and execute
- * the request which begin the journey of starting an activity.
- * @return The starter result.
- */
- int execute() {
- try {
- // Refuse possible leaked file descriptors
- if (mRequest.intent != null && mRequest.intent.hasFileDescriptors()) {
- throw new IllegalArgumentException("File descriptors passed in Intent");
- }
-
- final LaunchingState launchingState;
- synchronized (mService.mGlobalLock) {
- final ActivityRecord caller = ActivityRecord.forTokenLocked(mRequest.resultTo);
- final int callingUid = mRequest.realCallingUid == Request.DEFAULT_REAL_CALLING_UID
- ? Binder.getCallingUid() : mRequest.realCallingUid;
- launchingState = mSupervisor.getActivityMetricsLogger().notifyActivityLaunching(
- mRequest.intent, caller, callingUid);
- }
-
- // If the caller hasn't already resolved the activity, we're willing
- // to do so here. If the caller is already holding the WM lock here,
- // and we need to check dynamic Uri permissions, then we're forced
- // to assume those permissions are denied to avoid deadlocking.
- if (mRequest.activityInfo == null) {
- mRequest.resolveActivity(mSupervisor);
- }
-
- // Add checkpoint for this shutdown or reboot attempt, so we can record the original
- // intent action and package name.
- if (mRequest.intent != null) {
- String intentAction = mRequest.intent.getAction();
- String callingPackage = mRequest.callingPackage;
- if (intentAction != null && callingPackage != null
- && (Intent.ACTION_REQUEST_SHUTDOWN.equals(intentAction)
- || Intent.ACTION_SHUTDOWN.equals(intentAction)
- || Intent.ACTION_REBOOT.equals(intentAction))) {
- ShutdownCheckPoints.recordCheckPoint(intentAction, callingPackage, null);
- }
- }
-
- int res;
- synchronized (mService.mGlobalLock) {
- final boolean globalConfigWillChange = mRequest.globalConfig != null
- && mService.getGlobalConfiguration().diff(mRequest.globalConfig) != 0;
- final Task rootTask = mRootWindowContainer.getTopDisplayFocusedRootTask();
- if (rootTask != null) {
- rootTask.mConfigWillChange = globalConfigWillChange;
- }
- ProtoLog.v(WM_DEBUG_CONFIGURATION, "Starting activity when config "
- + "will change = %b", globalConfigWillChange);
-
- final long origId = Binder.clearCallingIdentity();
-
- res = resolveToHeavyWeightSwitcherIfNeeded();
- if (res != START_SUCCESS) {
- return res;
- }
- res = executeRequest(mRequest);
-
- Binder.restoreCallingIdentity(origId);
-
- if (globalConfigWillChange) {
- // If the caller also wants to switch to a new configuration, do so now.
- // This allows a clean switch, as we are waiting for the current activity
- // to pause (so we will not destroy it), and have not yet started the
- // next activity.
- mService.mAmInternal.enforceCallingPermission(
- android.Manifest.permission.CHANGE_CONFIGURATION,
- "updateConfiguration()");
- if (rootTask != null) {
- rootTask.mConfigWillChange = false;
- }
- ProtoLog.v(WM_DEBUG_CONFIGURATION,
- "Updating to new configuration after starting activity.");
-
- mService.updateConfigurationLocked(mRequest.globalConfig, null, false);
- }
-
- // The original options may have additional info about metrics. The mOptions is not
- // used here because it may be cleared in setTargetRootTaskIfNeeded.
- final ActivityOptions originalOptions = mRequest.activityOptions != null
- ? mRequest.activityOptions.getOriginalOptions() : null;
- // If the new record is the one that started, a new activity has created.
- final boolean newActivityCreated = mStartActivity == mLastStartActivityRecord;
- // Notify ActivityMetricsLogger that the activity has launched.
- // ActivityMetricsLogger will then wait for the windows to be drawn and populate
- // WaitResult.
- mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(launchingState, res,
- newActivityCreated, mLastStartActivityRecord, originalOptions);
- if (mRequest.waitResult != null) {
- mRequest.waitResult.result = res;
- res = waitResultIfNeeded(mRequest.waitResult, mLastStartActivityRecord,
- launchingState);
- }
- return getExternalResult(res);
- }
- } finally {
- onExecutionComplete();
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。