一張圖解Activity啓動流程圖

2017年的時候初次學習了下Activity啓動流程,最近在複習這個功能知識點的時候,發現忘記了許多,然後看了許多博客和書籍的資料,重新畫了一個流程圖,對照流程圖源碼流程就不會忘記的太快了。

 

我們現在來跟着流程圖走一遍:首先是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);
            }
        }
    }

摘取關鍵代碼如下,進入了  Instrumentation 的方法,什麼是Instrumentation ?

 Instrumentation.ActivityResult ar =
                mInstrumentation.execStartActivity(
                    this, mMainThread.getApplicationThread(), mToken, this,
                    intent, requestCode, options);

官方:An instrumentation that enables several advanced features and makes some hard guarantees about the state of the application under instrumentation.

初探它有哪些方法:(感興趣的可以自己去文檔看)https://developer.android.google.cn/reference/android/support/test/runner/MonitoringInstrumentation?hl=zh-tw

對了,沒錯最後的啓動操作activity的生命週期的方法還是靠它來執行的!

接着下一步往下走: mInstrumentation.execStartActivity()調用了ActivityManager     裏面的方法

 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()) {
                        result = am.onStartActivity(intent);
                    }
                    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();
            intent.prepareToLeaveProcess(who);
            int result = ActivityManager.getService()
                .startActivity(whoThread, who.getBasePackageName(), 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;
    }

代碼是不是有點多,不要方。看關鍵的代碼:

int result = ActivityManager.getService()
                .startActivity(whoThread, who.getBasePackageName(), intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        token, target != null ? target.mEmbeddedID : null,
                        requestCode, 0, null, options);

這裏的ActivityManager又是個什麼鬼?

官方:This class gives information about, and interacts with, activities, services, and the containing process.A number of the methods in this class are for debugging or informational purposes and they should not be used to affect any runtime behavior of your app. These methods are called out as such in the method level documentation.

這個類我們在開發應該經常用到吧,官方的說明也寫了可以拿到app相關的activities, services, and the containing process.不用過多的解釋吧

接着往下走:進入ActivityManager裏的代碼

 /**
     * @hide
     */
    public static IActivityManager getService() {
        return IActivityManagerSingleton.get();
    }

    private static final Singleton<IActivityManager> IActivityManagerSingleton =
            new Singleton<IActivityManager>() {
                @Override
                protected IActivityManager create() {
                    final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
                    final IActivityManager am = IActivityManager.Stub.asInterface(b);
                    return am;
                }
            };

我們來看看IActivityManager 是個什麼鬼?

看了我的截圖,是不是明白了 就是一個aidl啊,  熟系Binder機制的同學可能立馬反映過來了 原來是搞事情啊,是進行了進程的的通信啊,沒錯 ActivityManagerService簡稱AMS,它是android中很重要的一個服務,它統籌管理着android的四大組件;統一調度各應用進程;AMN由Binder類由Binder類派生,實現了IActivityManager接口,客戶端使用ActivityManager類,因爲AMS是系統核心服務,很多API不能直接訪問,需要通過ActivityManager,ActivityManager內部通過調用AMN的getDefault方法得到一個ActivityManagerProxy對象,通過它可與AMS通信。

熟悉binder的架構就只知道,是基於C/S架構進行通信的, 那麼IActivityManager am = IActivityManager.Stub.asInterface(b);相當於是客戶端,返回了一個服務端的代理對象,客戶端通過代理對象和服務端進行通信。那麼

public class ActivityManagerService extends IActivityManager.Stub
        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
.....
}
    

ActivityManagerService 又是IActivityManager.Stub的子類,我們通過這個代理類和系統進程進行通信。

我們在看看ActivityManagerService 的startActivity()

@Override
4461    public final int startActivity(IApplicationThread caller, String callingPackage,
4462            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4463            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4464        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4465                resultWho, requestCode, startFlags, profilerInfo, bOptions,
4466                UserHandle.getCallingUserId());
4467    }

最後調用了startActivityAsUser()

@Override
4490    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4491            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4492            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4493        enforceNotIsolatedCaller("startActivity");
4494        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4495                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4496        // TODO: Switch to user app stacks here.
4497        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4498                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4499                profilerInfo, null, null, bOptions, false, userId, null, null,
4500                "startActivityAsUser");
4501    }

又調用了 mActivityStarter.startActivityMayWait()  ActivityStarter又是什麼?

這個類谷歌文檔是木有的,我們只有看源碼我們看下它的註釋:

133/**
134 * Controller for interpreting how and then launching activities.
135 *
136 * This class collects all the logic for determining how an intent and flags should be turned into
137 * an activity and associated task and stack.
138 */
139class ActivityStarter {.......}

英文不大好大概翻譯下:該類收集用於確定如何將intent和標誌轉換爲一個activity以及相關的任務和堆棧。

我們在看下startActivityMayWait()都做了什麼事情?

 final int startActivityMayWait(IApplicationThread caller, int callingUid,
            String callingPackage, Intent intent, String resolvedType,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            IBinder resultTo, String resultWho, int requestCode, int startFlags,
            ProfilerInfo profilerInfo, WaitResult outResult,
            Configuration globalConfig, Bundle bOptions, boolean ignoreTargetSecurity, int userId,
            TaskRecord inTask, String reason) {
        // Refuse possible leaked file descriptors
        if (intent != null && intent.hasFileDescriptors()) {
            throw new IllegalArgumentException("File descriptors passed in Intent");
        }
        mSupervisor.mActivityMetricsLogger.notifyActivityLaunching();
        boolean componentSpecified = intent.getComponent() != null;

        // Save a copy in case ephemeral needs it
        final Intent ephemeralIntent = new Intent(intent);
        // Don't modify the client's object!
        intent = new Intent(intent);
        if (componentSpecified
                && intent.getData() != null
                && Intent.ACTION_VIEW.equals(intent.getAction())
                && mService.getPackageManagerInternalLocked()
                        .isInstantAppInstallerComponent(intent.getComponent())) {
            // intercept intents targeted directly to the ephemeral installer the
            // ephemeral installer should never be started with a raw URL; instead
            // adjust the intent so it looks like a "normal" instant app launch
            intent.setComponent(null /*component*/);
            componentSpecified = false;
        }

        ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId);
        if (rInfo == null) {
            UserInfo userInfo = mSupervisor.getUserInfo(userId);
            if (userInfo != null && userInfo.isManagedProfile()) {
                // Special case for managed profiles, if attempting to launch non-cryto aware
                // app in a locked managed profile from an unlocked parent allow it to resolve
                // as user will be sent via confirm credentials to unlock the profile.
                UserManager userManager = UserManager.get(mService.mContext);
                boolean profileLockedAndParentUnlockingOrUnlocked = false;
                long token = Binder.clearCallingIdentity();
                try {
                    UserInfo parent = userManager.getProfileParent(userId);
                    profileLockedAndParentUnlockingOrUnlocked = (parent != null)
                            && userManager.isUserUnlockingOrUnlocked(parent.id)
                            && !userManager.isUserUnlockingOrUnlocked(userId);
                } finally {
                    Binder.restoreCallingIdentity(token);
                }
                if (profileLockedAndParentUnlockingOrUnlocked) {
                    rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId,
                            PackageManager.MATCH_DIRECT_BOOT_AWARE
                                    | PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
                }
            }
        }
        // Collect information about the target of the Intent.
        ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);

        ActivityOptions options = ActivityOptions.fromBundle(bOptions);
        synchronized (mService) {
            final int realCallingPid = Binder.getCallingPid();
            final int realCallingUid = Binder.getCallingUid();
            int callingPid;
            if (callingUid >= 0) {
                callingPid = -1;
            } else if (caller == null) {
                callingPid = realCallingPid;
                callingUid = realCallingUid;
            } else {
                callingPid = callingUid = -1;
            }

            final ActivityStack stack = mSupervisor.mFocusedStack;
            stack.mConfigWillChange = globalConfig != null
                    && mService.getGlobalConfiguration().diff(globalConfig) != 0;
            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
                    "Starting activity when config will change = " + stack.mConfigWillChange);

            final long origId = Binder.clearCallingIdentity();

            if (aInfo != null &&
                    (aInfo.applicationInfo.privateFlags
                            & ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0) {
                // This may be a heavy-weight process!  Check to see if we already
                // have another, different heavy-weight process running.
                if (aInfo.processName.equals(aInfo.applicationInfo.packageName)) {
                    final ProcessRecord heavy = mService.mHeavyWeightProcess;
                    if (heavy != null && (heavy.info.uid != aInfo.applicationInfo.uid
                            || !heavy.processName.equals(aInfo.processName))) {
                        int appCallingUid = callingUid;
                        if (caller != null) {
                            ProcessRecord callerApp = mService.getRecordForAppLocked(caller);
                            if (callerApp != null) {
                                appCallingUid = callerApp.info.uid;
                            } else {
                                Slog.w(TAG, "Unable to find app for caller " + caller
                                        + " (pid=" + callingPid + ") when starting: "
                                        + intent.toString());
                                ActivityOptions.abort(options);
                                return ActivityManager.START_PERMISSION_DENIED;
                            }
                        }

                        IIntentSender target = mService.getIntentSenderLocked(
                                ActivityManager.INTENT_SENDER_ACTIVITY, "android",
                                appCallingUid, userId, null, null, 0, new Intent[] { intent },
                                new String[] { resolvedType }, PendingIntent.FLAG_CANCEL_CURRENT
                                        | PendingIntent.FLAG_ONE_SHOT, null);

                        Intent newIntent = new Intent();
                        if (requestCode >= 0) {
                            // Caller is requesting a result.
                            newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_HAS_RESULT, true);
                        }
                        newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_INTENT,
                                new IntentSender(target));
                        if (heavy.activities.size() > 0) {
                            ActivityRecord hist = heavy.activities.get(0);
                            newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_APP,
                                    hist.packageName);
                            newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_TASK,
                                    hist.getTask().taskId);
                        }
                        newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_NEW_APP,
                                aInfo.packageName);
                        newIntent.setFlags(intent.getFlags());
                        newIntent.setClassName("android",
                                HeavyWeightSwitcherActivity.class.getName());
                        intent = newIntent;
                        resolvedType = null;
                        caller = null;
                        callingUid = Binder.getCallingUid();
                        callingPid = Binder.getCallingPid();
                        componentSpecified = true;
                        rInfo = mSupervisor.resolveIntent(intent, null /*resolvedType*/, userId);
                        aInfo = rInfo != null ? rInfo.activityInfo : null;
                        if (aInfo != null) {
                            aInfo = mService.getActivityInfoForUser(aInfo, userId);
                        }
                    }
                }
            }

            final ActivityRecord[] outRecord = new ActivityRecord[1];
            int res = startActivityLocked(caller, intent, ephemeralIntent, resolvedType,
                    aInfo, rInfo, voiceSession, voiceInteractor,
                    resultTo, resultWho, requestCode, callingPid,
                    callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
                    options, ignoreTargetSecurity, componentSpecified, outRecord, inTask,
                    reason);

            Binder.restoreCallingIdentity(origId);

            if (stack.mConfigWillChange) {
                // 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.enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
                        "updateConfiguration()");
                stack.mConfigWillChange = false;
                if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
                        "Updating to new configuration after starting activity.");
                mService.updateConfigurationLocked(globalConfig, null, false);
            }

            if (outResult != null) {
                outResult.result = res;
                if (res == ActivityManager.START_SUCCESS) {
                    mSupervisor.mWaitingActivityLaunched.add(outResult);
                    do {
                        try {
                            mService.wait();
                        } catch (InterruptedException e) {
                        }
                    } while (outResult.result != START_TASK_TO_FRONT
                            && !outResult.timeout && outResult.who == null);
                    if (outResult.result == START_TASK_TO_FRONT) {
                        res = START_TASK_TO_FRONT;
                    }
                }
                if (res == START_TASK_TO_FRONT) {
                    final ActivityRecord r = outRecord[0];

                    // ActivityRecord may represent a different activity, but it should not be in
                    // the resumed state.
                    if (r.nowVisible && r.state == RESUMED) {
                        outResult.timeout = false;
                        outResult.who = r.realActivity;
                        outResult.totalTime = 0;
                        outResult.thisTime = 0;
                    } else {
                        outResult.thisTime = SystemClock.uptimeMillis();
                        mSupervisor.waitActivityVisible(r.realActivity, outResult);
                        // Note: the timeout variable is not currently not ever set.
                        do {
                            try {
                                mService.wait();
                            } catch (InterruptedException e) {
                            }
                        } while (!outResult.timeout && outResult.who == null);
                    }
                }
            }

            mSupervisor.mActivityMetricsLogger.notifyActivityLaunched(res, outRecord[0]);
            return res;
        }
    }

這代代碼是真夠長的,看到了是不是想放棄了,別急。慢慢看,其實這個方法裏面的乾貨也很多,來總結一下:

  1. 解析出與Intent相匹配的ActivityInfo。
  2. 得到啓動該Activity的Task,前臺Task。
  3. 通過startActivityLocked啓動Activity

好了那麼我們就看關鍵的點:startActivityLocked();

int res = startActivityLocked(caller, intent, ephemeralIntent, resolvedType,
                    aInfo, rInfo, voiceSession, voiceInteractor,
                    resultTo, resultWho, requestCode, callingPid,
                    callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
                    options, ignoreTargetSecurity, componentSpecified, outRecord, inTask,
                    reason);

具體看方法調用:

int startActivityLocked(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
            String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
            String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
            ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
            ActivityRecord[] outActivity, TaskRecord inTask, String reason) {

        if (TextUtils.isEmpty(reason)) {
            throw new IllegalArgumentException("Need to specify a reason.");
        }
        mLastStartReason = reason;
        mLastStartActivityTimeMs = System.currentTimeMillis();
        mLastStartActivityRecord[0] = null;

        mLastStartActivityResult = startActivity(caller, intent, ephemeralIntent, resolvedType,
                aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode,
                callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
                options, ignoreTargetSecurity, componentSpecified, mLastStartActivityRecord,
                inTask);

        if (outActivity != null) {
            // mLastStartActivityRecord[0] is set in the call to startActivity above.
            outActivity[0] = mLastStartActivityRecord[0];
        }

        // Aborted results are treated as successes externally, but we must track them internally.
        return mLastStartActivityResult != START_ABORTED ? mLastStartActivityResult : START_SUCCESS;
    }

實際調用了ActivityStarter的startActivity   我們來具體看看方法實現:

 private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
            ActivityRecord[] outActivity) {
        int result = START_CANCELED;
        try {
            mService.mWindowManager.deferSurfaceLayout();
            result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
                    startFlags, doResume, options, inTask, outActivity);
        } finally {
            // If we are not able to proceed, disassociate the activity from the task. Leaving an
            // activity in an incomplete state can lead to issues, such as performing operations
            // without a window container.
            if (!ActivityManager.isStartResultSuccessful(result)
                    && mStartActivity.getTask() != null) {
                mStartActivity.getTask().removeActivity(mStartActivity);
            }
            mService.mWindowManager.continueSurfaceLayout();
        }

        postStartActivityProcessing(r, result, mSupervisor.getLastStack().mStackId,  mSourceRecord,
                mTargetStack);

        return result;
    }

我們還是關係下主流程  其中又調用了startActivityUnchecked

 private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
            ActivityRecord[] outActivity) {

        setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,
                voiceInteractor);

        computeLaunchingTaskFlags();

        computeSourceStack();

        mIntent.setFlags(mLaunchFlags);

        ActivityRecord reusedActivity = getReusableIntentActivity();

        final int preferredLaunchStackId =
                (mOptions != null) ? mOptions.getLaunchStackId() : INVALID_STACK_ID;
        final int preferredLaunchDisplayId =
                (mOptions != null) ? mOptions.getLaunchDisplayId() : DEFAULT_DISPLAY;

        if (reusedActivity != null) {
            // When the flags NEW_TASK and CLEAR_TASK are set, then the task gets reused but
            // still needs to be a lock task mode violation since the task gets cleared out and
            // the device would otherwise leave the locked task.
            if (mSupervisor.isLockTaskModeViolation(reusedActivity.getTask(),
                    (mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
                            == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))) {
                mSupervisor.showLockTaskToast();
                Slog.e(TAG, "startActivityUnchecked: Attempt to violate Lock Task Mode");
                return START_RETURN_LOCK_TASK_MODE_VIOLATION;
            }

            if (mStartActivity.getTask() == null) {
                mStartActivity.setTask(reusedActivity.getTask());
            }
            if (reusedActivity.getTask().intent == null) {
                // This task was started because of movement of the activity based on affinity...
                // Now that we are actually launching it, we can assign the base intent.
                reusedActivity.getTask().setIntent(mStartActivity);
            }

            // This code path leads to delivering a new intent, we want to make sure we schedule it
            // as the first operation, in case the activity will be resumed as a result of later
            // operations.
            if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0
                    || isDocumentLaunchesIntoExisting(mLaunchFlags)
                    || mLaunchSingleInstance || mLaunchSingleTask) {
                final TaskRecord task = reusedActivity.getTask();

                // In this situation we want to remove all activities from the task up to the one
                // being started. In most cases this means we are resetting the task to its initial
                // state.
                final ActivityRecord top = task.performClearTaskForReuseLocked(mStartActivity,
                        mLaunchFlags);

                // The above code can remove {@code reusedActivity} from the task, leading to the
                // the {@code ActivityRecord} removing its reference to the {@code TaskRecord}. The
                // task reference is needed in the call below to
                // {@link setTargetStackAndMoveToFrontIfNeeded}.
                if (reusedActivity.getTask() == null) {
                    reusedActivity.setTask(task);
                }

                if (top != null) {
                    if (top.frontOfTask) {
                        // Activity aliases may mean we use different intents for the top activity,
                        // so make sure the task now has the identity of the new intent.
                        top.getTask().setIntent(mStartActivity);
                    }
                    deliverNewIntent(top);
                }
            }

            sendPowerHintForLaunchStartIfNeeded(false /* forceSend */, reusedActivity);

            reusedActivity = setTargetStackAndMoveToFrontIfNeeded(reusedActivity);

            final ActivityRecord outResult =
                    outActivity != null && outActivity.length > 0 ? outActivity[0] : null;

            // When there is a reused activity and the current result is a trampoline activity,
            // set the reused activity as the result.
            if (outResult != null && (outResult.finishing || outResult.noDisplay)) {
                outActivity[0] = reusedActivity;
            }

            if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
                // We don't need to start a new activity, and the client said not to do anything
                // if that is the case, so this is it!  And for paranoia, make sure we have
                // correctly resumed the top activity.
                resumeTargetStackIfNeeded();
                return START_RETURN_INTENT_TO_CALLER;
            }
            setTaskFromIntentActivity(reusedActivity);

            if (!mAddingToTask && mReuseTask == null) {
                // We didn't do anything...  but it was needed (a.k.a., client don't use that
                // intent!)  And for paranoia, make sure we have correctly resumed the top activity.
                resumeTargetStackIfNeeded();
                if (outActivity != null && outActivity.length > 0) {
                    outActivity[0] = reusedActivity;
                }

                return START_TASK_TO_FRONT;
            }
        }

        if (mStartActivity.packageName == null) {
            final ActivityStack sourceStack = mStartActivity.resultTo != null
                    ? mStartActivity.resultTo.getStack() : null;
            if (sourceStack != null) {
                sourceStack.sendActivityResultLocked(-1 /* callingUid */, mStartActivity.resultTo,
                        mStartActivity.resultWho, mStartActivity.requestCode, RESULT_CANCELED,
                        null /* data */);
            }
            ActivityOptions.abort(mOptions);
            return START_CLASS_NOT_FOUND;
        }

        // If the activity being launched is the same as the one currently at the top, then
        // we need to check if it should only be launched once.
        final ActivityStack topStack = mSupervisor.mFocusedStack;
        final ActivityRecord topFocused = topStack.topActivity();
        final ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(mNotTop);
        final boolean dontStart = top != null && mStartActivity.resultTo == null
                && top.realActivity.equals(mStartActivity.realActivity)
                && top.userId == mStartActivity.userId
                && top.app != null && top.app.thread != null
                && ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
                || mLaunchSingleTop || mLaunchSingleTask);
        if (dontStart) {
            // For paranoia, make sure we have correctly resumed the top activity.
            topStack.mLastPausedActivity = null;
            if (mDoResume) {
                mSupervisor.resumeFocusedStackTopActivityLocked();
            }
            ActivityOptions.abort(mOptions);
            if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
                // We don't need to start a new activity, and the client said not to do
                // anything if that is the case, so this is it!
                return START_RETURN_INTENT_TO_CALLER;
            }

            deliverNewIntent(top);

            // Don't use mStartActivity.task to show the toast. We're not starting a new activity
            // but reusing 'top'. Fields in mStartActivity may not be fully initialized.
            mSupervisor.handleNonResizableTaskIfNeeded(top.getTask(), preferredLaunchStackId,
                    preferredLaunchDisplayId, topStack.mStackId);

            return START_DELIVERED_TO_TOP;
        }

        boolean newTask = false;
        final TaskRecord taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null)
                ? mSourceRecord.getTask() : null;

        // Should this be considered a new task?
        int result = START_SUCCESS;
        if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
                && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
            newTask = true;
            result = setTaskFromReuseOrCreateNewTask(
                    taskToAffiliate, preferredLaunchStackId, topStack);
        } else if (mSourceRecord != null) {
            result = setTaskFromSourceRecord();
        } else if (mInTask != null) {
            result = setTaskFromInTask();
        } else {
            // This not being started from an existing activity, and not part of a new task...
            // just put it in the top task, though these days this case should never happen.
            setTaskToCurrentTopOrCreateNewTask();
        }
        if (result != START_SUCCESS) {
            return result;
        }

        mService.grantUriPermissionFromIntentLocked(mCallingUid, mStartActivity.packageName,
                mIntent, mStartActivity.getUriPermissionsLocked(), mStartActivity.userId);
        mService.grantEphemeralAccessLocked(mStartActivity.userId, mIntent,
                mStartActivity.appInfo.uid, UserHandle.getAppId(mCallingUid));
        if (mSourceRecord != null) {
            mStartActivity.getTask().setTaskToReturnTo(mSourceRecord);
        }
        if (newTask) {
            EventLog.writeEvent(
                    EventLogTags.AM_CREATE_TASK, mStartActivity.userId,
                    mStartActivity.getTask().taskId);
        }
        ActivityStack.logStartActivity(
                EventLogTags.AM_CREATE_ACTIVITY, mStartActivity, mStartActivity.getTask());
        mTargetStack.mLastPausedActivity = null;

        sendPowerHintForLaunchStartIfNeeded(false /* forceSend */, mStartActivity);

        mTargetStack.startActivityLocked(mStartActivity, topFocused, newTask, mKeepCurTransition,
                mOptions);
        if (mDoResume) {
            final ActivityRecord topTaskActivity =
                    mStartActivity.getTask().topRunningActivityLocked();
            if (!mTargetStack.isFocusable()
                    || (topTaskActivity != null && topTaskActivity.mTaskOverlay
                    && mStartActivity != topTaskActivity)) {
                // If the activity is not focusable, we can't resume it, but still would like to
                // make sure it becomes visible as it starts (this will also trigger entry
                // animation). An example of this are PIP activities.
                // Also, we don't want to resume activities in a task that currently has an overlay
                // as the starting activity just needs to be in the visible paused state until the
                // over is removed.
                mTargetStack.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
                // Go ahead and tell window manager to execute app transition for this activity
                // since the app transition will not be triggered through the resume channel.
                mWindowManager.executeAppTransition();
            } else {
                // If the target stack was not previously focusable (previous top running activity
                // on that stack was not visible) then any prior calls to move the stack to the
                // will not update the focused stack.  If starting the new activity now allows the
                // task stack to be focusable, then ensure that we now update the focused stack
                // accordingly.
                if (mTargetStack.isFocusable() && !mSupervisor.isFocusedStack(mTargetStack)) {
                    mTargetStack.moveToFront("startActivityUnchecked");
                }
                mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,
                        mOptions);
            }
        } else {
            mTargetStack.addRecentActivityLocked(mStartActivity);
        }
        mSupervisor.updateUserStackLocked(mStartActivity.userId, mTargetStack);

        mSupervisor.handleNonResizableTaskIfNeeded(mStartActivity.getTask(), preferredLaunchStackId,
                preferredLaunchDisplayId, mTargetStack.mStackId);

        return START_SUCCESS;
    }

這裏摘要別人的總結:首先setInitialState()、computeLaunchingTaskFlags()、computeSourceStack()驗證是否是特定的FLAG,後面執行了不同啓動模式下的不同棧的處理。這些處理中關鍵的方法是mSupervisor.resumeFocusedStackTopActivityLocked()  其中 mSupervisor是該類的成員變量: ActivityStackSupervisor mSupervisor;

我們看下這個ActivityStackSupervisor 又是個什麼?

我們看下這個 方法的具體實現mSupervisor.resumeFocusedStackTopActivityLocked() 

   boolean resumeFocusedStackTopActivityLocked() {
        return resumeFocusedStackTopActivityLocked(null, null, null);
    }

    boolean resumeFocusedStackTopActivityLocked(
            ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
        ...

            mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
        ...
        return false;
    }

    boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
        ...
            result = resumeTopActivityInnerLocked(prev, options);
        ...
        return result;
    }

    private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
        ...

        mStackSupervisor.startSpecificActivityLocked(next, true, true);

        ...

    }

    void startSpecificActivityLocked(ActivityRecord r,
                boolean andResume, boolean checkConfig) {

        ...

        realStartActivityLocked(r, app, andResume, checkConfig);

        ...

    }

    final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
                boolean andResume, boolean checkConfig) throws RemoteException {
        ...

        app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
                        System.identityHashCode(r), r.info,
                        // TODO: Have this take the merged configuration instead of separate global and
                        // override configs.
                        mergedConfiguration.getGlobalConfiguration(),
                        mergedConfiguration.getOverrideConfiguration(), r.compat,
                        r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
                        r.persistentState, results, newIntents, !andResume,
                        mService.isNextTransitionForward(), profilerInfo);

我們看下最後     app.thread.scheduleLaunchActivity(.........)這個方法,這個方法參數有點多,thread是IApplicationThread類型,ApplicationThread繼承了IApplicationThread.Stub,因此app.thread是一個IApplicationThread的代理對象。和IActivityManager一樣,app.thread調用scheduleLaunchActivity方法,通過Binder機制,會使ApplicationThread的scheduleLaunchActivity方法被調用。由此實現了第二次的進程間的通信,將啓動Activity的操作交還給了ApplicationThread類。 

又回到了我們熟悉的ActivityThread裏了,ApplicationThread是ActivityThread的內部類,因此ApplicationThread可以調用外部類ActivityThread的方法,也就是說,啓動Activity的操作交給了ActivityThread來處理。

  private class ApplicationThread extends IApplicationThread.Stub {
..........//代理類
scheduleLaunchActivity();
}

我們要看下這個方法具體作了什麼?scheduleLauchActivty();

 // we use token to identify this activity without having to send the
749        // activity itself back to the activity manager. (matters more with ipc)
750        @Override
751        public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
752                ActivityInfo info, Configuration curConfig, Configuration overrideConfig,
753                CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,
754                int procState, Bundle state, PersistableBundle persistentState,
755                List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
756                boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {
757
758            updateProcessState(procState, false);
759
760            ActivityClientRecord r = new ActivityClientRecord();
761
762            r.token = token;
763            r.ident = ident;
764            r.intent = intent;
765            r.referrer = referrer;
766            r.voiceInteractor = voiceInteractor;
767            r.activityInfo = info;
768            r.compatInfo = compatInfo;
769            r.state = state;
770            r.persistentState = persistentState;
771
772            r.pendingResults = pendingResults;
773            r.pendingIntents = pendingNewIntents;
774
775            r.startsNotResumed = notResumed;
776            r.isForward = isForward;
777
778            r.profilerInfo = profilerInfo;
779
780            r.overrideConfig = overrideConfig;
781            updatePendingConfiguration(curConfig);
782
783            sendMessage(H.LAUNCH_ACTIVITY, r);
784        }

看到這個783行,或許我們就明白了 sendMessage(H.LAUNCH_ACTIVITY, r);在ActivityThread中有個 H內部類,我們上代碼看看都有什麼?先看下sendMessage();裏面具體實現

 private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
2645        if (DEBUG_MESSAGES) Slog.v(
2646            TAG, "SCHEDULE " + what + " " + mH.codeToString(what)
2647            + ": " + arg1 + " / " + obj);
2648        Message msg = Message.obtain();
2649        msg.what = what;
2650        msg.obj = obj;
2651        msg.arg1 = arg1;
2652        msg.arg2 = arg2;
2653        if (async) {
2654            msg.setAsynchronous(true);
2655        }
2656        mH.sendMessage(msg);
2657    }
 private class H extends Handler {
1463       
1521
1522        String codeToString(int code) {
1523            if (DEBUG_MESSAGES) {
1524                switch (code) {
1525                    case LAUNCH_ACTIVITY: return "LAUNCH_ACTIVITY";
1526                    case PAUSE_ACTIVITY: return "PAUSE_ACTIVITY";
1527                    case PAUSE_ACTIVITY_FINISHING: return "PAUSE_ACTIVITY_FINISHING";
1528                    case STOP_ACTIVITY_SHOW: return "STOP_ACTIVITY_SHOW";
1529                    case STOP_ACTIVITY_HIDE: return "STOP_ACTIVITY_HIDE";
1530                    case SHOW_WINDOW: return "SHOW_WINDOW";
1531                    case HIDE_WINDOW: return "HIDE_WINDOW";
1532                    case RESUME_ACTIVITY: return "RESUME_ACTIVITY";
1533                    case SEND_RESULT: return "SEND_RESULT";
1534                    case DESTROY_ACTIVITY: return "DESTROY_ACTIVITY";
1535                    case BIND_APPLICATION: return "BIND_APPLICATION";
1536                    case EXIT_APPLICATION: return "EXIT_APPLICATION";
1537                    case NEW_INTENT: return "NEW_INTENT";
1538                    case RECEIVER: return "RECEIVER";
1539                    case CREATE_SERVICE: return "CREATE_SERVICE";
1540                    case SERVICE_ARGS: return "SERVICE_ARGS";
1541                    case STOP_SERVICE: return "STOP_SERVICE";
1542                    case CONFIGURATION_CHANGED: return "CONFIGURATION_CHANGED";
1543                    case CLEAN_UP_CONTEXT: return "CLEAN_UP_CONTEXT";
1544                    case GC_WHEN_IDLE: return "GC_WHEN_IDLE";
1545                    case BIND_SERVICE: return "BIND_SERVICE";
1546                    case UNBIND_SERVICE: return "UNBIND_SERVICE";
1547                    case DUMP_SERVICE: return "DUMP_SERVICE";
1548                    case LOW_MEMORY: return "LOW_MEMORY";
1549                    case ACTIVITY_CONFIGURATION_CHANGED: return "ACTIVITY_CONFIGURATION_CHANGED";
1550                    case ACTIVITY_MOVED_TO_DISPLAY: return "ACTIVITY_MOVED_TO_DISPLAY";
1551                    case RELAUNCH_ACTIVITY: return "RELAUNCH_ACTIVITY";
1552                    case PROFILER_CONTROL: return "PROFILER_CONTROL";
1553                    case CREATE_BACKUP_AGENT: return "CREATE_BACKUP_AGENT";
1554                    case DESTROY_BACKUP_AGENT: return "DESTROY_BACKUP_AGENT";
1555                    case SUICIDE: return "SUICIDE";
1556                    case REMOVE_PROVIDER: return "REMOVE_PROVIDER";
1557                    case ENABLE_JIT: return "ENABLE_JIT";
1558                    case DISPATCH_PACKAGE_BROADCAST: return "DISPATCH_PACKAGE_BROADCAST";
1559                    case SCHEDULE_CRASH: return "SCHEDULE_CRASH";
1560                    case DUMP_HEAP: return "DUMP_HEAP";
1561                    case DUMP_ACTIVITY: return "DUMP_ACTIVITY";
1562                    case SLEEPING: return "SLEEPING";
1563                    case SET_CORE_SETTINGS: return "SET_CORE_SETTINGS";
1564                    case UPDATE_PACKAGE_COMPATIBILITY_INFO: return "UPDATE_PACKAGE_COMPATIBILITY_INFO";
1565                    case TRIM_MEMORY: return "TRIM_MEMORY";
1566                    case DUMP_PROVIDER: return "DUMP_PROVIDER";
1567                    case UNSTABLE_PROVIDER_DIED: return "UNSTABLE_PROVIDER_DIED";
1568                    case REQUEST_ASSIST_CONTEXT_EXTRAS: return "REQUEST_ASSIST_CONTEXT_EXTRAS";
1569                    case TRANSLUCENT_CONVERSION_COMPLETE: return "TRANSLUCENT_CONVERSION_COMPLETE";
1570                    case INSTALL_PROVIDER: return "INSTALL_PROVIDER";
1571                    case ON_NEW_ACTIVITY_OPTIONS: return "ON_NEW_ACTIVITY_OPTIONS";
1572                    case CANCEL_VISIBLE_BEHIND: return "CANCEL_VISIBLE_BEHIND";
1573                    case BACKGROUND_VISIBLE_BEHIND_CHANGED: return "BACKGROUND_VISIBLE_BEHIND_CHANGED";
1574                    case ENTER_ANIMATION_COMPLETE: return "ENTER_ANIMATION_COMPLETE";
1575                    case MULTI_WINDOW_MODE_CHANGED: return "MULTI_WINDOW_MODE_CHANGED";
1576                    case PICTURE_IN_PICTURE_MODE_CHANGED: return "PICTURE_IN_PICTURE_MODE_CHANGED";
1577                    case LOCAL_VOICE_INTERACTION_STARTED: return "LOCAL_VOICE_INTERACTION_STARTED";
1578                    case ATTACH_AGENT: return "ATTACH_AGENT";
1579                    case APPLICATION_INFO_CHANGED: return "APPLICATION_INFO_CHANGED";
1580                }
1581            }
1582            return Integer.toString(code);
1583        }
1584        public void handleMessage(Message msg) {
1585            if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
1586            switch (msg.what) {
1587                case LAUNCH_ACTIVITY: {
1588                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
1589                    final ActivityClientRecord r = (ActivityClientRecord) msg.obj;
1590
1591                    r.packageInfo = getPackageInfoNoCheck(
1592                            r.activityInfo.applicationInfo, r.compatInfo);
1593                    handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
1594                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1595                } break;
1596                case RELAUNCH_ACTIVITY: {
1597                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityRestart");
1598                    ActivityClientRecord r = (ActivityClientRecord)msg.obj;
1599                    handleRelaunchActivity(r);
1600                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1601                } break;
1602                case PAUSE_ACTIVITY: {
1603                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
1604                    SomeArgs args = (SomeArgs) msg.obj;
1605                    handlePauseActivity((IBinder) args.arg1, false,
1606                            (args.argi1 & USER_LEAVING) != 0, args.argi2,
1607                            (args.argi1 & DONT_REPORT) != 0, args.argi3);
1608                    maybeSnapshot();
1609                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1610                } break;
1611                case PAUSE_ACTIVITY_FINISHING: {
1612                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
1613                    SomeArgs args = (SomeArgs) msg.obj;
1614                    handlePauseActivity((IBinder) args.arg1, true, (args.argi1 & USER_LEAVING) != 0,
1615                            args.argi2, (args.argi1 & DONT_REPORT) != 0, args.argi3);
1616                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1617                } break;
1618                case STOP_ACTIVITY_SHOW: {
1619                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStop");
1620                    SomeArgs args = (SomeArgs) msg.obj;
1621                    handleStopActivity((IBinder) args.arg1, true, args.argi2, args.argi3);
1622                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1623                } break;
1624                case STOP_ACTIVITY_HIDE: {
1625                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStop");
1626                    SomeArgs args = (SomeArgs) msg.obj;
1627                    handleStopActivity((IBinder) args.arg1, false, args.argi2, args.argi3);
1628                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1629                } break;
1630                case SHOW_WINDOW:
1631                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityShowWindow");
1632                    handleWindowVisibility((IBinder)msg.obj, true);
1633                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1634                    break;
1635                case HIDE_WINDOW:
1636                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityHideWindow");
1637                    handleWindowVisibility((IBinder)msg.obj, false);
1638                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1639                    break;
1640                case RESUME_ACTIVITY:
1641                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityResume");
1642                    SomeArgs args = (SomeArgs) msg.obj;
1643                    handleResumeActivity((IBinder) args.arg1, true, args.argi1 != 0, true,
1644                            args.argi3, "RESUME_ACTIVITY");
1645                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1646                    break;
1647                case SEND_RESULT:
1648                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityDeliverResult");
1649                    handleSendResult((ResultData)msg.obj);
1650                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1651                    break;
1652                case DESTROY_ACTIVITY:
1653                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityDestroy");
1654                    handleDestroyActivity((IBinder)msg.obj, msg.arg1 != 0,
1655                            msg.arg2, false);
1656                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1657                    break;
1658                case BIND_APPLICATION:
1659                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
1660                    AppBindData data = (AppBindData)msg.obj;
1661                    handleBindApplication(data);
1662                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1663                    break;
1664                case EXIT_APPLICATION:
1665                    if (mInitialApplication != null) {
1666                        mInitialApplication.onTerminate();
1667                    }
1668                    Looper.myLooper().quit();
1669                    break;
1670                case NEW_INTENT:
1671                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityNewIntent");
1672                    handleNewIntent((NewIntentData)msg.obj);
1673                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1674                    break;
1675                case RECEIVER:
1676                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastReceiveComp");
1677                    handleReceiver((ReceiverData)msg.obj);
1678                    maybeSnapshot();
1679                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1680                    break;
1681                case CREATE_SERVICE:
1682                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, ("serviceCreate: " + String.valueOf(msg.obj)));
1683                    handleCreateService((CreateServiceData)msg.obj);
1684                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1685                    break;
1686                case BIND_SERVICE:
1687                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceBind");
1688                    handleBindService((BindServiceData)msg.obj);
1689                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1690                    break;
1691                case UNBIND_SERVICE:
1692                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceUnbind");
1693                    handleUnbindService((BindServiceData)msg.obj);
1694                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1695                    break;
1696                case SERVICE_ARGS:
1697                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, ("serviceStart: " + String.valueOf(msg.obj)));
1698                    handleServiceArgs((ServiceArgsData)msg.obj);
1699                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1700                    break;
1701                case STOP_SERVICE:
1702                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceStop");
1703                    handleStopService((IBinder)msg.obj);
1704                    maybeSnapshot();
1705                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1706                    break;
1707                case CONFIGURATION_CHANGED:
1708                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "configChanged");
1709                    mCurDefaultDisplayDpi = ((Configuration)msg.obj).densityDpi;
1710                    mUpdatingSystemConfig = true;
1711                    try {
1712                        handleConfigurationChanged((Configuration) msg.obj, null);
1713                    } finally {
1714                        mUpdatingSystemConfig = false;
1715                    }
1716                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1717                    break;
1718                case CLEAN_UP_CONTEXT:
1719                    ContextCleanupInfo cci = (ContextCleanupInfo)msg.obj;
1720                    cci.context.performFinalCleanup(cci.who, cci.what);
1721                    break;
1722                case GC_WHEN_IDLE:
1723                    scheduleGcIdler();
1724                    break;
1725                case DUMP_SERVICE:
1726                    handleDumpService((DumpComponentInfo)msg.obj);
1727                    break;
1728                case LOW_MEMORY:
1729                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "lowMemory");
1730                    handleLowMemory();
1731                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1732                    break;
1733                case ACTIVITY_CONFIGURATION_CHANGED:
1734                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityConfigChanged");
1735                    handleActivityConfigurationChanged((ActivityConfigChangeData) msg.obj,
1736                            INVALID_DISPLAY);
1737                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1738                    break;
1739                case ACTIVITY_MOVED_TO_DISPLAY:
1740                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityMovedToDisplay");
1741                    handleActivityConfigurationChanged((ActivityConfigChangeData) msg.obj,
1742                            msg.arg1 /* displayId */);
1743                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1744                    break;
1745                case PROFILER_CONTROL:
1746                    handleProfilerControl(msg.arg1 != 0, (ProfilerInfo)msg.obj, msg.arg2);
1747                    break;
1748                case CREATE_BACKUP_AGENT:
1749                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "backupCreateAgent");
1750                    handleCreateBackupAgent((CreateBackupAgentData)msg.obj);
1751                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1752                    break;
1753                case DESTROY_BACKUP_AGENT:
1754                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "backupDestroyAgent");
1755                    handleDestroyBackupAgent((CreateBackupAgentData)msg.obj);
1756                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1757                    break;
1758                case SUICIDE:
1759                    Process.killProcess(Process.myPid());
1760                    break;
1761                case REMOVE_PROVIDER:
1762                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "providerRemove");
1763                    completeRemoveProvider((ProviderRefCount)msg.obj);
1764                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1765                    break;
1766                case ENABLE_JIT:
1767                    ensureJitEnabled();
1768                    break;
1769                case DISPATCH_PACKAGE_BROADCAST:
1770                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastPackage");
1771                    handleDispatchPackageBroadcast(msg.arg1, (String[])msg.obj);
1772                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1773                    break;
1774                case SCHEDULE_CRASH:
1775                    throw new RemoteServiceException((String)msg.obj);
1776                case DUMP_HEAP:
1777                    handleDumpHeap(msg.arg1 != 0, (DumpHeapData)msg.obj);
1778                    break;
1779                case DUMP_ACTIVITY:
1780                    handleDumpActivity((DumpComponentInfo)msg.obj);
1781                    break;
1782                case DUMP_PROVIDER:
1783                    handleDumpProvider((DumpComponentInfo)msg.obj);
1784                    break;
1785                case SLEEPING:
1786                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "sleeping");
1787                    handleSleeping((IBinder)msg.obj, msg.arg1 != 0);
1788                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1789                    break;
1790                case SET_CORE_SETTINGS:
1791                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "setCoreSettings");
1792                    handleSetCoreSettings((Bundle) msg.obj);
1793                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1794                    break;
1795                case UPDATE_PACKAGE_COMPATIBILITY_INFO:
1796                    handleUpdatePackageCompatibilityInfo((UpdateCompatibilityData)msg.obj);
1797                    break;
1798                case TRIM_MEMORY:
1799                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "trimMemory");
1800                    handleTrimMemory(msg.arg1);
1801                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1802                    break;
1803                case UNSTABLE_PROVIDER_DIED:
1804                    handleUnstableProviderDied((IBinder)msg.obj, false);
1805                    break;
1806                case REQUEST_ASSIST_CONTEXT_EXTRAS:
1807                    handleRequestAssistContextExtras((RequestAssistContextExtras)msg.obj);
1808                    break;
1809                case TRANSLUCENT_CONVERSION_COMPLETE:
1810                    handleTranslucentConversionComplete((IBinder)msg.obj, msg.arg1 == 1);
1811                    break;
1812                case INSTALL_PROVIDER:
1813                    handleInstallProvider((ProviderInfo) msg.obj);
1814                    break;
1815                case ON_NEW_ACTIVITY_OPTIONS:
1816                    Pair<IBinder, ActivityOptions> pair = (Pair<IBinder, ActivityOptions>) msg.obj;
1817                    onNewActivityOptions(pair.first, pair.second);
1818                    break;
1819                case CANCEL_VISIBLE_BEHIND:
1820                    handleCancelVisibleBehind((IBinder) msg.obj);
1821                    break;
1822                case BACKGROUND_VISIBLE_BEHIND_CHANGED:
1823                    handleOnBackgroundVisibleBehindChanged((IBinder) msg.obj, msg.arg1 > 0);
1824                    break;
1825                case ENTER_ANIMATION_COMPLETE:
1826                    handleEnterAnimationComplete((IBinder) msg.obj);
1827                    break;
1828                case START_BINDER_TRACKING:
1829                    handleStartBinderTracking();
1830                    break;
1831                case STOP_BINDER_TRACKING_AND_DUMP:
1832                    handleStopBinderTrackingAndDump((ParcelFileDescriptor) msg.obj);
1833                    break;
1834                case MULTI_WINDOW_MODE_CHANGED:
1835                    handleMultiWindowModeChanged((IBinder) ((SomeArgs) msg.obj).arg1,
1836                            ((SomeArgs) msg.obj).argi1 == 1,
1837                            (Configuration) ((SomeArgs) msg.obj).arg2);
1838                    break;
1839                case PICTURE_IN_PICTURE_MODE_CHANGED:
1840                    handlePictureInPictureModeChanged((IBinder) ((SomeArgs) msg.obj).arg1,
1841                            ((SomeArgs) msg.obj).argi1 == 1,
1842                            (Configuration) ((SomeArgs) msg.obj).arg2);
1843                    break;
1844                case LOCAL_VOICE_INTERACTION_STARTED:
1845                    handleLocalVoiceInteractionStarted((IBinder) ((SomeArgs) msg.obj).arg1,
1846                            (IVoiceInteractor) ((SomeArgs) msg.obj).arg2);
1847                    break;
1848                case ATTACH_AGENT:
1849                    handleAttachAgent((String) msg.obj);
1850                    break;
1851                case APPLICATION_INFO_CHANGED:
1852                    mUpdatingSystemConfig = true;
1853                    try {
1854                        handleApplicationInfoChanged((ApplicationInfo) msg.obj);
1855                    } finally {
1856                        mUpdatingSystemConfig = false;
1857                    }
1858                    break;
1859            }
1860          
1865        }

源碼有點長,我們就看啓動這個case吧

  case LAUNCH_ACTIVITY: {
                        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
                        final ActivityClientRecord r = (ActivityClientRecord) msg.obj;
                        r.packageInfo = getPackageInfoNoCheck(
                                r.activityInfo.applicationInfo, r.compatInfo);
                        handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
                        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
 }

調用ActivityThread的handleLaunchActivity方法啓動Activity,源碼如下:

 private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
2873        // If we are getting ready to gc after going to the background, well
2874        // we are back active so skip it.
2875        unscheduleGcIdler();
2876        mSomeActivitiesChanged = true;
2877
2878        if (r.profilerInfo != null) {
2879            mProfiler.setProfiler(r.profilerInfo);
2880            mProfiler.startProfiling();
2881        }
2882
2883        // Make sure we are running with the most recent config.
2884        handleConfigurationChanged(null, null);
2885
2886        if (localLOGV) Slog.v(
2887            TAG, "Handling launch of " + r);
2888
2889        // Initialize before creating the activity
2890        WindowManagerGlobal.initialize();
2891
2892        Activity a = performLaunchActivity(r, customIntent);
2893
2894        if (a != null) {
2895            r.createdConfig = new Configuration(mConfiguration);
2896            reportSizeConfigurations(r);
2897            Bundle oldState = r.state;
2898            handleResumeActivity(r.token, false, r.isForward,
2899                    !r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);
2900
2901            if (!r.activity.mFinished && r.startsNotResumed) {
2902                // The activity manager actually wants this one to start out paused, because it
2903                // needs to be visible but isn't in the foreground. We accomplish this by going
2904                // through the normal startup (because activities expect to go through onResume()
2905                // the first time they run, before their window is displayed), and then pausing it.
2906                // However, in this case we do -not- need to do the full pause cycle (of freezing
2907                // and such) because the activity manager assumes it can just retain the current
2908                // state it has.
2909                performPauseActivityIfNeeded(r, reason);
2910
2911                // We need to keep around the original state, in case we need to be created again.
2912                // But we only do this for pre-Honeycomb apps, which always save their state when
2913                // pausing, so we can not have them save their state when restarting from a paused
2914                // state. For HC and later, we want to (and can) let the state be saved as the
2915                // normal part of stopping the activity.
2916                if (r.isPreHoneycomb()) {
2917                    r.state = oldState;
2918                }
2919            }
2920        } else {
2921            // If there was an error, for any reason, tell the activity manager to stop us.
2922            try {
2923                ActivityManager.getService()
2924                    .finishActivity(r.token, Activity.RESULT_CANCELED, null,
2925                            Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
2926            } catch (RemoteException ex) {
2927                throw ex.rethrowFromSystemServer();
2928            }
2929        }
2930    }

關鍵代碼 Activity a = performLaunchActivity(r, customIntent);來返回一個Activity,若Activity不爲空,則調用handleResumeActivity方法,內部會調用Activity$onResume方法。當Activity爲空,也就是創建Activity的實例出錯了,最終會調用ActivityManagerService$finishActivity方法。也就是說,當創建Activity實例出錯後,停止啓動Activity的具體操作交給ActivityManagerService來處理。

我們來看下performLaunchActivity()這個方法


2683    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
2684        // System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")");
2685
2686        ActivityInfo aInfo = r.activityInfo;
2687        if (r.packageInfo == null) {
2688            r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
2689                    Context.CONTEXT_INCLUDE_CODE);
2690        }
2691
2692        ComponentName component = r.intent.getComponent();
2693        if (component == null) {
2694            component = r.intent.resolveActivity(
2695                mInitialApplication.getPackageManager());
2696            r.intent.setComponent(component);
2697        }
2698
2699        if (r.activityInfo.targetActivity != null) {
2700            component = new ComponentName(r.activityInfo.packageName,
2701                    r.activityInfo.targetActivity);
2702        }
2703
2704        ContextImpl appContext = createBaseContextForActivity(r);
2705        Activity activity = null;
2706        try {
2707            java.lang.ClassLoader cl = appContext.getClassLoader();
2708            activity = mInstrumentation.newActivity(
2709                    cl, component.getClassName(), r.intent);
2710            StrictMode.incrementExpectedActivityCount(activity.getClass());
2711            r.intent.setExtrasClassLoader(cl);
2712            r.intent.prepareToEnterProcess();
2713            if (r.state != null) {
2714                r.state.setClassLoader(cl);
2715            }
2716        } catch (Exception e) {
2717            if (!mInstrumentation.onException(activity, e)) {
2718                throw new RuntimeException(
2719                    "Unable to instantiate activity " + component
2720                    + ": " + e.toString(), e);
2721            }
2722        }
2723
2724        try {
2725            Application app = r.packageInfo.makeApplication(false, mInstrumentation);
2726
2727            if (localLOGV) Slog.v(TAG, "Performing launch of " + r);
2728            if (localLOGV) Slog.v(
2729                    TAG, r + ": app=" + app
2730                    + ", appName=" + app.getPackageName()
2731                    + ", pkg=" + r.packageInfo.getPackageName()
2732                    + ", comp=" + r.intent.getComponent().toShortString()
2733                    + ", dir=" + r.packageInfo.getAppDir());
2734
2735            if (activity != null) {
2736                CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
2737                Configuration config = new Configuration(mCompatConfiguration);
2738                if (r.overrideConfig != null) {
2739                    config.updateFrom(r.overrideConfig);
2740                }
2741                if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
2742                        + r.activityInfo.name + " with config " + config);
2743                Window window = null;
2744                if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {
2745                    window = r.mPendingRemoveWindow;
2746                    r.mPendingRemoveWindow = null;
2747                    r.mPendingRemoveWindowManager = null;
2748                }
2749                appContext.setOuterContext(activity);
2750                activity.attach(appContext, this, getInstrumentation(), r.token,
2751                        r.ident, app, r.intent, r.activityInfo, title, r.parent,
2752                        r.embeddedID, r.lastNonConfigurationInstances, config,
2753                        r.referrer, r.voiceInteractor, window, r.configCallback);
2754
2755                if (customIntent != null) {
2756                    activity.mIntent = customIntent;
2757                }
2758                r.lastNonConfigurationInstances = null;
2759                checkAndBlockForNetworkAccess();
2760                activity.mStartedActivity = false;
2761                int theme = r.activityInfo.getThemeResource();
2762                if (theme != 0) {
2763                    activity.setTheme(theme);
2764                }
2765
2766                activity.mCalled = false;
2767                if (r.isPersistable()) {
2768                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
2769                } else {
2770                    mInstrumentation.callActivityOnCreate(activity, r.state);
2771                }
2772                if (!activity.mCalled) {
2773                    throw new SuperNotCalledException(
2774                        "Activity " + r.intent.getComponent().toShortString() +
2775                        " did not call through to super.onCreate()");
2776                }
2777                r.activity = activity;
2778                r.stopped = true;
2779                if (!r.activity.mFinished) {
2780                    activity.performStart();
2781                    r.stopped = false;
2782                }
2783                if (!r.activity.mFinished) {
2784                    if (r.isPersistable()) {
2785                        if (r.state != null || r.persistentState != null) {
2786                            mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,
2787                                    r.persistentState);
2788                        }
2789                    } else if (r.state != null) {
2790                        mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
2791                    }
2792                }
2793                if (!r.activity.mFinished) {
2794                    activity.mCalled = false;
2795                    if (r.isPersistable()) {
2796                        mInstrumentation.callActivityOnPostCreate(activity, r.state,
2797                                r.persistentState);
2798                    } else {
2799                        mInstrumentation.callActivityOnPostCreate(activity, r.state);
2800                    }
2801                    if (!activity.mCalled) {
2802                        throw new SuperNotCalledException(
2803                            "Activity " + r.intent.getComponent().toShortString() +
2804                            " did not call through to super.onPostCreate()");
2805                    }
2806                }
2807            }
2808            r.paused = true;
2809
2810            mActivities.put(r.token, r);
2811
2812        } catch (SuperNotCalledException e) {
2813            throw e;
2814
2815        } catch (Exception e) {
2816            if (!mInstrumentation.onException(activity, e)) {
2817                throw new RuntimeException(
2818                    "Unable to start activity " + component
2819                    + ": " + e.toString(), e);
2820            }
2821        }
2822
2823        return activity;
2824    }

是不是很長,我們看關鍵的代碼:activity = mInstrumentation.newActivity( cl, component.getClassName(), r.intent);  mInstrumentation這個又回到開篇第一個講的類了 Instrumentation,忘記了的小夥伴可以再去看一下。

mInstrumentation.newActivity( cl, component.getClassName(), r.intent);  的源碼如下:

public Activity newActivity(ClassLoader cl, String className,
                Intent intent)
                throws InstantiationException, IllegalAccessException,
                ClassNotFoundException {
            return (Activity)cl.loadClass(className).newInstance();
        }

Application app = r.loadedApk.makeApplication(false, mInstrumentation);

public Application makeApplication(boolean forceDefaultAppClass,
            Instrumentation instrumentation) {
        if (mApplication != null) {
            return mApplication;
        }

    Application app = null;

    //...

    app = mActivityThread.mInstrumentation.newApplication(
                    cl, appClass, appContext);

    //...

    mApplication = app;

    instrumentation.callApplicationOnCreate(app);
    //...

    return app;
}

獲取要啓動的Activity的ComponentName對象:裏面包含了包名,類名相關的信息;調用newActivity方法,attach方法後啓動Activity(調用Instrumentation$callActivityOnCreate方法)​​​​​​​
終於到了最後的關鍵:創建Activity,創建Application,調用Attach,最後mInstrumentation.callActivityOnCreate(activity, r.state);

public void callActivityOnCreate(Activity activity, Bundle icicle) {
            prePerformCreate(activity);
            activity.performCreate(icicle);
            postPerformCreate(activity);
    }
    final void performCreate(Bundle icicle) {
            restoreHasCurrentPermissionRequest(icicle);
            onCreate(icicle);
            mActivityTransitionState.readState(icicle);
            performCreateCommon();
    }

本文完!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章