AndroidM源碼學(xué)習(xí)——AMS之Activity的啟動(dòng)

首先上圖,有一個(gè)宏觀的了解市框,然后再細(xì)看每個(gè)函數(shù)都主要做了什么霞扬。


Activity的啟動(dòng).gif

前面幾個(gè)函數(shù)的逐層調(diào)用就不說(shuō)了,函數(shù)的重載拾给,從Activity的startActivityForResult方法開(kāi)始

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

ActivityResult是一個(gè)內(nèi)部類祥得,它的外部類Instrumentation是安卓?jī)?nèi)部測(cè)試框架的一部分兔沃,在execStartActivity方法中會(huì)對(duì)Activity做監(jiān)視與檢查

     final int N = mActivityMonitors.size();
                for (int i=0; i<N; i++) {
                    final ActivityMonitor am = mActivityMonitors.get(i);
    ···
      int result = ActivityManagerNative.getDefault()
                .startActivityAsCaller(whoThread, who.getBasePackageName(), intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        token, target != null ? target.mEmbeddedID : null,
                        requestCode, 0, null, options, ignoreTargetSecurity, userId);
            checkStartActivityResult(result, intent);
    ···

ActivityMonitor同樣是一個(gè)內(nèi)部類蒋得,它用于在自動(dòng)化測(cè)試中對(duì)Activity的啟動(dòng)作監(jiān)視,checkStartActivityResult方法用來(lái)檢查Activity是否異常乒疏,如在XML中未聲明等問(wèn)題额衙,一些典型的檢查內(nèi)部如下所求:

if (intent instanceof Intent && ((Intent)intent).getComponent() != null)
                    throw new ActivityNotFoundException(
                            "Unable to find explicit activity class "
                            + ((Intent)intent).getComponent().toShortString()
                            + "; have you declared this activity in your AndroidManifest.xml?");
                throw new ActivityNotFoundException(
                        "No Activity found to handle " + intent);
            case ActivityManager.START_PERMISSION_DENIED:
                throw new SecurityException("Not allowed to start activity "
                        + intent);
            case ActivityManager.START_PERMISSION_USER_DENIED:
                Log.e(TAG, "User denied to start activity with intent: " + intent);
                return;
            case ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT:
                throw new AndroidRuntimeException(
                        "FORWARD_RESULT_FLAG used while also requesting a result");
            case ActivityManager.START_NOT_ACTIVITY:
                throw new IllegalArgumentException(
                        "PendingIntent is not an activity");
            case ActivityManager.START_NOT_VOICE_COMPATIBLE:
                throw new SecurityException(
                        "Starting under voice control not allowed for: " + intent);
            case ActivityManager.START_NOT_CURRENT_USER_ACTIVITY:
                // Fail silently for this case so we don't break current apps.
                // TODO(b/22929608): Instead of failing silently or throwing an exception,
                // we should properly position the activity in the stack (i.e. behind all current
                // user activity/task) and not change the positioning of stacks.
                Log.e(TAG,
                        "Not allowed to start background user activity that shouldn't be displayed"
                        + " for all users. Failing silently...");

    ...

result返回結(jié)果通過(guò)代理模式由ActivityManagerService來(lái)最終實(shí)現(xiàn)返回
在AMS中,startActivity調(diào)用startActivityAsUser然后調(diào)用了ActivityStackSupervisor的startActivityMayWait方法怕吴。(Task是以堆棧形式組織Activity的集合窍侧,而Task又由ActivityStack管理,ActivityStackSupervisor則是管理ActivityStack的類)

//執(zhí)行權(quán)限檢查
        // Collect information about the target of the Intent.
        ActivityInfo aInfo =
                resolveActivity(intent, resolvedType, startFlags, profilerInfo, userId);

        // M: To check permission for start application. @{
        if (MobileManagerUtils.isSupported()) {
            int uid = Binder.getCallingUid();
            if (!MobileManagerUtils.checkIntentPermission(intent, aInfo, mService.mContext, uid)) {
                Slog.e(TAG, "startActivity() is not granted with permission: " +
                        aInfo.permission + " from uid: " + uid);
                return ActivityManager.START_PERMISSION_USER_DENIED;
            }
        }
        // @}   
//如果APP有PRIVATE_FLAG_CANT_SAVE_STATE標(biāo)記則為heavy-weight process
 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)) {
        if (mService.mHeavyWeightProcess != null &&
                (mService.mHeavyWeightProcess.info.uid != aInfo.applicationInfo.uid ||
                !mService.mHeavyWeightProcess.processName.equals(aInfo.processName))) {
            int appCallingUid = callingUid;
···
//調(diào)用startActivityLocked方法
            int res = startActivityLocked(caller, intent, resolvedType, aInfo,
                    voiceSession, voiceInteractor, resultTo, resultWho,
                    requestCode, callingPid, callingUid, callingPackage,
                    realCallingPid, realCallingUid, startFlags, options, ignoreTargetSecurity,
                    componentSpecified, null, container, inTask);
//之后查看config是否改變
            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(config, null, false, false);
            }

在final int startActivityLocked()方法中

 ···
 //創(chuàng)建ProcessRecord
   ProcessRecord callerApp = null;
        if (caller != null) {
            callerApp = mService.getRecordForAppLocked(caller);
            if (callerApp != null) {
                callingPid = callerApp.pid;
                callingUid = callerApp.info.uid;
            } else {
                Slog.w(TAG, "Unable to find app for caller " + caller
                      + " (pid=" + callingPid + ") when starting: "
                      + intent.toString());
                err = ActivityManager.START_PERMISSION_DENIED;
            }
        }
        ···
// 創(chuàng)建ActivityRecord
         ActivityRecord sourceRecord = null;
        ActivityRecord resultRecord = null;
        if (resultTo != null) {
            sourceRecord = isInAnyStackLocked(resultTo);
            if (DEBUG_RESULTS) Slog.v(TAG_RESULTS,
                    "Will send result to " + resultTo + " " + sourceRecord);
            if (sourceRecord != null) {
                if (requestCode >= 0 && !sourceRecord.finishing) {
                    resultRecord = sourceRecord;
                }
            }
        }
        ···
//得到ActivityRecord
        ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,
                intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho,
                requestCode, componentSpecified, voiceSession != null, this, container, options);
//調(diào)用startActivityUncheckedLocked()
        err = startActivityUncheckedLocked(r, sourceRecord, voiceSession, voiceInteractor,
                startFlags, true, options, inTask);

在startActivityUncheckedLocked方法中判斷Activity的啟動(dòng)方式

        final boolean launchSingleTop = r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP;
        final boolean launchSingleInstance = r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE;
        final boolean launchSingleTask = r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK;
        int launchFlags = intent.getFlags();
//查找Task,確定是否需要?jiǎng)?chuàng)建新的Task
 // We may want to try to place the new activity in to an existing task.  We always
        // do this if the target activity is singleTask or singleInstance; we will also do
        // this if NEW_TASK has been requested, and there is not an additional qualifier telling
        // us to still place it in a new task: multi task, always doc mode, or being asked to
        // launch this as a new task behind the current one.
        if (((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
                (launchFlags & Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
                || launchSingleInstance || launchSingleTask) {
            // If bring to front is requested, and no result is requested and we have not
            // been given an explicit task to launch in to, and
            // we can find a task that was started with this same
            // component, then instead of launching bring that one to the front.
            if (inTask == null && r.resultTo == null) {
                // See if there is a task to bring to the front.  If this is
                // a SINGLE_INSTANCE activity, there can be one and only one
                // instance of it in the history, and it is always in its own
                // unique task, so we do a special search.
                ActivityRecord intentActivity = !launchSingleInstance ?
                        findTaskLocked(r) : findActivityLocked(intent, r.info);
                if (intentActivity != 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 (isLockTaskModeViolation(intentActivity.task,
                            (launchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
                            == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))) {
                        showLockTaskToast();
                        Slog.e(TAG, "startActivityUnchecked: Attempt to violate Lock Task Mode");
                        return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
                    }
                    if (r.task == null) {
                        r.task = intentActivity.task;
                    }
    //以下幾種情況要?jiǎng)?chuàng)建新的棧
 if (inTask == null) {
            if (sourceRecord == null) {
                // This activity is not being started from another...  in this
                // case we -always- start a new task.
                if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) == 0 && inTask == null) {
                    Slog.w(TAG, "startActivity called from non-Activity context; forcing " +
                            "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
                    launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
                }
            } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
                // The original activity who is starting us is running as a single
                // instance...  this new activity it is starting must go on its
                // own task.
                launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
            } else if (launchSingleInstance || launchSingleTask) {
                // The activity being started is a single instance...  it always
                // gets launched into its own task.
                launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
            }
        }
    
    //如不為空且目標(biāo)不是棧頂转绷,則將目標(biāo)移動(dòng)到棧頂
    // If the target task is not in the front, then we need
    // to bring it to the front...  except...  well, with
    // SINGLE_TASK_LAUNCH it's not entirely clear.  We'd like
    // to have the same behavior as if a new instance was
    // being started, which means not bringing it to the front
    // if the caller is not itself in the front.
    final ActivityStack focusStack = getFocusedStack();
    ActivityRecord curTop = (focusStack == null)
            ? null : focusStack.topRunningNonDelayedActivityLocked(notTop);
    boolean movedToFront = false;
    if (curTop != null && (curTop.task != intentActivity.task ||
            curTop.task != focusStack.topTask())) {
        r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
        if (sourceRecord == null || (sourceStack.topActivity() != null &&
                sourceStack.topActivity().task == sourceRecord.task)) {
            // We really do want to push this one into the user's face, right now.
            if (launchTaskBehind && sourceRecord != null) {
                intentActivity.setTaskToAffiliateWith(sourceRecord.task);
            }
            movedHome = true;
            targetStack.moveTaskToFrontLocked(intentActivity.task, noAnimation,
                    options, r.appTimeTracker, "bringingFoundTaskToFront");
            movedToFront = true;
            if ((launchFlags &
                    (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME))
                    == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) {
                // Caller wants to appear on home activity.
                intentActivity.task.setTaskToReturnTo(HOME_ACTIVITY_TYPE);
            }
            options = null;

            /// M: Fix ALPS01276300, at this case, avoid move home to top when resume top @{
            intentActivity.task.mMovingToFront = true;
            Slog.d(TAG_TASKS, "Set intentActivity.task.mMovingToFront = true");
            /// @}
        }
    }
    if (!movedToFront) {
        if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Bring to front target: " + targetStack
                + " from " + intentActivity);
        targetStack.moveToFront("intentActivityFound");
    }
    
    //如果棧頂即為目標(biāo)Activity直接resumeTopActivitiesLocked();
  if (r.packageName != null) {
            // 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.
            ActivityStack topStack = mFocusedStack;
            ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(notTop);
            if (top != null && r.resultTo == null) {
                if (top.realActivity.equals(r.realActivity) && top.userId == r.userId) {
                    if (top.app != null && top.app.thread != null) {
                        if ((launchFlags & Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
                            || launchSingleTop || launchSingleTask) {
                            ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, top,
                                    top.task);
                            /// M: AMS log enhancement @{
                            if (!ActivityManagerService.IS_USER_BUILD)
                               Slog.d(TAG, "ACT-AM_NEW_INTENT " + top + top.task);
                            /// @}
                            // For paranoia, make sure we have correctly
                            // resumed the top activity.
                            topStack.mLastPausedActivity = null;
                            if (doResume) {
                                resumeTopActivitiesLocked();
                            }
                            ActivityOptions.abort(options);
                            if ((startFlags&ActivityManager.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 ActivityManager.START_RETURN_INTENT_TO_CALLER;
                            }
                            top.deliverNewIntentLocked(callingUid, r.intent, r.launchedFromPackage);
                            return ActivityManager.START_DELIVERED_TO_TOP;
                        }
                    }
                }
            }

        } 
//創(chuàng)建一個(gè)新的Task并置于棧頂
    ActivityRecord prev = targetStack.topActivity();
    r.setTask(prev != null ? prev.task : targetStack.createTaskRecord(getNextTaskId(),
                    r.info, intent, null, null, true), null);
    mWindowManager.moveTaskToTop(r.task.taskId);
    if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + r
            + " in new guessed " + r.task);
//最后由AMS給權(quán)限并啟動(dòng)
mService.grantUriPermissionFromIntentLocked(callingUid, r.packageName,
                intent, r.getUriPermissionsLocked(), r.userId);
···
ActivityStack.logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task);
/// M: AMS log enhancement @{
if (!ActivityManagerService.IS_USER_BUILD)
   Slog.d(TAG, "ACT-AM_CREATE_ACTIVITY " + r + r.task);
/// @}

targetStack.mLastPausedActivity = null;
targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options);
if (!launchTaskBehind) {
    // Don't set focus on an activity that's going to the back.
    mService.setFocusedActivityLocked(r, "startedActivity");
}

在ActivityStack的startActivityLocked方法中加入窗口管理WindowManager

if ((r.intent.getFlags() & Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) {
                mWindowManager.prepareAppTransition(AppTransition.TRANSIT_NONE, keepCurTransition);
                mNoAnimActivities.add(r);
            } else {
                mWindowManager.prepareAppTransition(newTask
                        ? r.mLaunchTaskBehind
                                ? AppTransition.TRANSIT_TASK_OPEN_BEHIND
                                : AppTransition.TRANSIT_TASK_OPEN
                        : AppTransition.TRANSIT_ACTIVITY_OPEN, keepCurTransition);
                mNoAnimActivities.remove(r);
            }
            mWindowManager.addAppToken(task.mActivities.indexOf(r),
                    r.appToken, r.task.taskId, mStackId, r.info.screenOrientation, r.fullscreen,
                    (r.info.flags & ActivityInfo.FLAG_SHOW_FOR_ALL_USERS) != 0, r.userId,
                    r.info.configChanges, task.voiceSession != null, r.mLaunchTaskBehind);

如果可見(jiàn)堆棧的頂部與焦點(diǎn)堆棧相同則調(diào)用ActivityStackSupervisor的resumeTopActivitiesLocked方法伟件,而在該方法中調(diào)用resumeTopActivityInnerLocked方法移動(dòng)焦點(diǎn)

//將焦點(diǎn)移到下一個(gè)可見(jiàn)的正在運(yùn)行的activity
 final String reason = "noMoreActivities";
if (!mFullscreen) {
    // Try to move focus to the next visible stack with a running activity if this
    // stack is not covering the entire screen.
    final ActivityStack stack = getNextVisibleStackLocked();
    if (adjustFocusToNextVisibleStackLocked(stack, reason)) {
        return mStackSupervisor.resumeTopActivitiesLocked(stack, prev, null);
    }
}
// Let's just start up the Launcher...
ActivityOptions.abort(options);                 
//如果需要?jiǎng)t中斷當(dāng)前的Activity
// We need to start pausing the current activity so the top one
// can be resumed...
boolean dontWaitForPause = (next.info.flags&ActivityInfo.FLAG_RESUME_WHILE_PAUSING) != 0;
boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, true, dontWaitForPause);
if (mResumedActivity != null) {
    if (DEBUG_STATES) Slog.d(TAG_STATES,
            "resumeTopActivityLocked: Pausing " + mResumedActivity);
    pausing |= startPausingLocked(userLeaving, false, true, dontWaitForPause);
}
//將暫停的Activity置為不可見(jiàn),新的Activity置為可見(jiàn),之后通知wm
 if (prev != null && prev != next) {
    if (!mStackSupervisor.mWaitingVisibleActivities.contains(prev)
            && next != null && !next.nowVisible) {
        mStackSupervisor.mWaitingVisibleActivities.add(prev);
        if (DEBUG_SWITCH) Slog.v(TAG_SWITCH,
                "Resuming top, waiting visible to hide: " + prev);
    } else {
        // The next activity is already visible, so hide the previous
        // activity's windows right now so we can show the new one ASAP.
        // We only do this if the previous is finishing, which should mean
        // it is on top of the one being resumed so hiding it quickly
        // is good.  Otherwise, we want to do the normal route of allowing
        // the resumed activity to be shown so we can decide if the
        // previous should actually be hidden depending on whether the
        // new one is found to be full-screen or not.
        if (prev.finishing) {
            mWindowManager.setAppVisibility(prev.appToken, false);
            if (DEBUG_SWITCH) Slog.v(TAG_SWITCH,
                    "Not waiting for visible to hide: " + prev + ", waitingVisible="
                    + mStackSupervisor.mWaitingVisibleActivities.contains(prev)
                    + ", nowVisible=" + next.nowVisible);
        } else {
            if (DEBUG_SWITCH) Slog.v(TAG_SWITCH,
                    "Previous already visible but still waiting to hide: " + prev
                    + ", waitingVisible="
                    + mStackSupervisor.mWaitingVisibleActivities.contains(prev)
                    + ", nowVisible=" + next.nowVisible);
        }
    }
}
···
if (prev.finishing) {
    if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION,
            "Prepare close transition: prev=" + prev);
    if (mNoAnimActivities.contains(prev)) {
        anim = false;
        mWindowManager.prepareAppTransition(AppTransition.TRANSIT_NONE, false);
    } else {
        mWindowManager.prepareAppTransition(prev.task == next.task
                ? AppTransition.TRANSIT_ACTIVITY_CLOSE
                : AppTransition.TRANSIT_TASK_CLOSE, false);
    }
    mWindowManager.setAppWillBeHidden(prev.appToken);
    mWindowManager.setAppVisibility(prev.appToken, false);
} else {
    if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION,
            "Prepare open transition: prev=" + prev);
    if (mNoAnimActivities.contains(next)) {
        anim = false;
        mWindowManager.prepareAppTransition(AppTransition.TRANSIT_NONE, false);
    } else {
        mWindowManager.prepareAppTransition(prev.task == next.task
                ? AppTransition.TRANSIT_ACTIVITY_OPEN
                : next.mLaunchTaskBehind
                        ? AppTransition.TRANSIT_TASK_OPEN_BEHIND
                        : AppTransition.TRANSIT_TASK_OPEN, false);
    }
}       
//如果Activity所在進(jìn)程存在议经,先恢復(fù)其狀態(tài)
next.sleeping = false;
mService.showAskCompatModeDialogLocked(next);
next.app.pendingUiClean = true;
next.app.forceProcessStateUpTo(mService.mTopProcessState);
next.clearOptionsLocked();
next.app.thread.scheduleResumeActivity(next.appToken, next.app.repProcState,
        mService.isNextTransitionForward(), resumeAnimOptions);
mStackSupervisor.checkReadyForSleepLocked();

然后調(diào)用ActivityStackSupervisor的startSpecificActivityLocked方法

void startSpecificActivityLocked(ActivityRecord r,
        boolean andResume, boolean checkConfig) {
    // Is this activity's application already running?
    ProcessRecord app = mService.getProcessRecordLocked(r.processName,
            r.info.applicationInfo.uid, true);

    r.task.stack.setLaunchTime(r);

    if (app != null && app.thread != null) {
        try {
            if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
                    || !"android".equals(r.info.packageName)) {
                // Don't add this if it is a platform component that is marked
                // to run in multiple processes, because this is actually
                // part of the framework so doesn't make sense to track as a
                // separate apk in the process.
                app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode,
                        mService.mProcessStats);
            }
            //如果不是第一次啟動(dòng)直接startActivity
            realStartActivityLocked(r, app, andResume, checkConfig);
            return;
        } catch (RemoteException e) {
            Slog.w(TAG, "Exception when starting activity "
                    + r.intent.getComponent().flattenToShortString(), e);
        }

        // If a dead object exception was thrown -- fall through to
        // restart the application.
    }
            //如果是第一次啟動(dòng)斧账,需要?jiǎng)?chuàng)建新的進(jìn)程
    mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
            "activity", r.intent.getComponent(), false, false, true);
}

ActivityManagerService的startProcessLocked方法創(chuàng)建新的進(jìn)程

 Process.ProcessStartResult startResult = Process.start(entryPoint,
                    app.processName, uid, uid, gids, debugFlags, mountExternal,
                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
                    app.info.dataDir, entryPointArgs);

那么新創(chuàng)建的這個(gè)進(jìn)程如何與要啟動(dòng)的Activity關(guān)聯(lián)在一起呢,我們知道煞肾,Activity的真正入口是ActivityThread的main方法咧织,核心操作如下

Looper.prepareMainLooper();
ActivityThread thread = new ActivityThread();
thread.attach(false);

在此attach方法中做進(jìn)程與應(yīng)用的綁定

RuntimeInit.setApplicationObject(mAppThread.asBinder());
final IActivityManager mgr = ActivityManagerNative.getDefault();
try {
    mgr.attachApplication(mAppThread);
} catch (RemoteException ex) {
    // Ignore
}

通過(guò)代理它的真正實(shí)現(xiàn)位于AMS的attachApplicationLocked

thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
        profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
        app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
        isRestrictedBackupMode || !normalMode, app.persistent,
        new Configuration(mConfiguration), app.compat,
        getCommonServicesLocked(app.isolated),
        mCoreSettingsObserver.getCoreSettingsLocked());
//之后交給ASS啟動(dòng)
// See if the top visible activity is waiting to run in this process...
if (normalMode) {
    try {
        if (mStackSupervisor.attachApplicationLocked(app)) {
            didSomething = true;
        }
    } catch (Exception e) {
        Slog.e(TAG, "Exception thrown launching activities in " + app, e);
        Slog.e(TAG, Log.getStackTraceString(new Throwable()));
        badApp = true;
    }
}

回到ActivityStackSupervisor,調(diào)用attachApplicationLocked方法籍救,查詢棧頂Activity然后啟動(dòng)

ActivityRecord hr = stack.topRunningActivityLocked(null);
if (hr != null) {
    if (hr.app == null && app.uid == hr.info.applicationInfo.uid
            && processName.equals(hr.processName)) {
        try {
            if (realStartActivityLocked(hr, app, true, true)) {
                didSomething = true;
            }
        } catch (RemoteException e) {
            Slog.w(TAG, "Exception in new application when starting activity "
                  + hr.intent.getComponent().flattenToShortString(), e);
            throw e;
        }
    }
}

在realStartActivityLocked方法中會(huì)對(duì)Configuration的狀態(tài)是否改變進(jìn)行檢查

if (checkConfig) {
    Configuration config = mWindowManager.updateOrientationFromAppTokens(
            mService.mConfiguration,
            r.mayFreezeScreenLocked(app) ? r.appToken : null);
    mService.updateConfigurationLocked(config, r, false, false);
}

通知Activity所在進(jìn)程進(jìn)行啟動(dòng)

app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
        System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),
        new Configuration(stack.mOverrideConfig), r.compat, r.launchedFromPackage,
        task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results,
        newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo);

在ActivityThread的scheduleLaunchActivity方法中使用Message發(fā)送消息

ActivityClientRecord r = new ActivityClientRecord();

r.token = token;
r.ident = ident;
r.intent = intent;
r.referrer = referrer;
r.voiceInteractor = voiceInteractor;
r.activityInfo = info;
r.compatInfo = compatInfo;
r.state = state;
r.persistentState = persistentState;

r.pendingResults = pendingResults;
r.pendingIntents = pendingNewIntents;

r.startsNotResumed = notResumed;
r.isForward = isForward;

r.profilerInfo = profilerInfo;

r.overrideConfig = overrideConfig;
updatePendingConfiguration(curConfig);

sendMessage(H.LAUNCH_ACTIVITY, r);

private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
    Message msg = Message.obtain();
    msg.what = what;
    msg.obj = obj;
    msg.arg1 = arg1;
    msg.arg2 = arg2;
    if (async) {
        msg.setAsynchronous(true);
    }
    mH.sendMessage(msg);
}

Thread收到消息后調(diào)用handlerLaunchActivity方法得到啟動(dòng)的Activity

 Activity a = performLaunchActivity(r, customIntent);
 //performLaunchActivity方法使用類的加載器加載得到相應(yīng)的activity
 Activity activity = null;
try {
    java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
    activity = mInstrumentation.newActivity(
            cl, component.getClassName(), r.intent);
    StrictMode.incrementExpectedActivityCount(activity.getClass());
    r.intent.setExtrasClassLoader(cl);
    r.intent.prepareToEnterProcess();
    if (r.state != null) {
        r.state.setClassLoader(cl);
    }
} catch (Exception e) {
    if (!mInstrumentation.onException(activity, e)) {
        throw new RuntimeException(
            "Unable to instantiate activity " + component
            + ": " + e.toString(), e);
    }
}

在performLaunchActivity方法中獲取Activity的配置信息(Configuration习绢、Theme等),然后調(diào)用Activity生命周期的方法

try {
    Application app = r.packageInfo.makeApplication(false, mInstrumentation);
    if (activity != null) {
        Context appContext = createBaseContextForActivity(r, activity);
        CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
        Configuration config = new Configuration(mCompatConfiguration);
        if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
                + r.activityInfo.name + " with config " + config);
        activity.attach(appContext, this, getInstrumentation(), r.token,
                r.ident, app, r.intent, r.activityInfo, title, r.parent,
                r.embeddedID, r.lastNonConfigurationInstances, config,
                r.referrer, r.voiceInteractor); 
                if (customIntent != null) {
            activity.mIntent = customIntent;
        }
        r.lastNonConfigurationInstances = null;
        activity.mStartedActivity = false;
        int theme = r.activityInfo.getThemeResource();
        if (theme != 0) {
            activity.setTheme(theme);
        }

        activity.mCalled = false;
        if (r.isPersistable()) {
            mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
        } else {
            mInstrumentation.callActivityOnCreate(activity, r.state);
        }
        if (!activity.mCalled) {
            throw new SuperNotCalledException(
                "Activity " + r.intent.getComponent().toShortString() +
                " did not call through to super.onCreate()");
        }
        r.activity = activity;
        r.stopped = true;
        if (!r.activity.mFinished) {
            activity.performStart();
            r.stopped = false;
        }
        ···
    }
}

補(bǔ)充一下當(dāng)前Activity被pause的幾個(gè)方法:
ActivityStack的startPausingLocke方法
通過(guò)Proxy調(diào)用ApplicationThread的schedulePauseActivity方法

prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,
        userLeaving, prev.configChangeFlags, dontWait);

在activity開(kāi)始啟動(dòng)的過(guò)程中保持設(shè)備處于喚醒狀態(tài)蝙昙,并停止按鍵的分發(fā)

// If we are not going to sleep, we want to ensure the device is
// awake until the next activity is started.
if (!uiSleeping && !mService.isSleepingOrShuttingDown()) {
    mStackSupervisor.acquireLaunchWakelock();
}
...
 // Have the window manager pause its key dispatching until the new
// activity has started.  If we're pausing the activity just because
// the screen is being turned off and the UI is sleeping, don't interrupt
// key dispatch; the same activity will pick it up again on wakeup.
if (!uiSleeping) {
    prev.pauseKeyDispatchingLocked();
} 

在schedulePauseActivity方法中通過(guò)Message發(fā)送消息闪萄,同理handlerMessage中調(diào)用handlePauseActivity梧却,然后調(diào)用AMS的activityPaused方法

try {
        ActivityManagerNative.getDefault().activityPaused(token);
    } catch (RemoteException ex) {
}

ActivityManagerService的activityPaused方法

@Override
public final void activityPaused(IBinder token) {
    final long origId = Binder.clearCallingIdentity();
    synchronized(this) {
        ActivityStack stack = ActivityRecord.getStackLocked(token);
        if (stack != null) {
            stack.activityPausedLocked(token, false);
        }
    }
    Binder.restoreCallingIdentity(origId);
}

調(diào)用ActivityStack的activityPausedLocked方法,在activityPausedLocked中再調(diào)用completePauseLocked方法败去,之后回到ActivityStackSupervisor的resumeTopActivitiesLocked方法

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末篮幢,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子为迈,更是在濱河造成了極大的恐慌三椿,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,194評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件葫辐,死亡現(xiàn)場(chǎng)離奇詭異搜锰,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)耿战,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門蛋叼,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人剂陡,你說(shuō)我怎么就攤上這事狈涮。” “怎么了鸭栖?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,780評(píng)論 0 346
  • 文/不壞的土叔 我叫張陵歌馍,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我晕鹊,道長(zhǎng)松却,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,388評(píng)論 1 283
  • 正文 為了忘掉前任溅话,我火速辦了婚禮晓锻,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘飞几。我一直安慰自己砚哆,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,430評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布屑墨。 她就那樣靜靜地躺著躁锁,像睡著了一般。 火紅的嫁衣襯著肌膚如雪绪钥。 梳的紋絲不亂的頭發(fā)上灿里,一...
    開(kāi)封第一講書(shū)人閱讀 49,764評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音程腹,去河邊找鬼匣吊。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的色鸳。 我是一名探鬼主播社痛,決...
    沈念sama閱讀 38,907評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼命雀!你這毒婦竟也來(lái)了蒜哀?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,679評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤吏砂,失蹤者是張志新(化名)和其女友劉穎撵儿,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體狐血,經(jīng)...
    沈念sama閱讀 44,122評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡淀歇,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,459評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了匈织。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片浪默。...
    茶點(diǎn)故事閱讀 38,605評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖缀匕,靈堂內(nèi)的尸體忽然破棺而出纳决,到底是詐尸還是另有隱情,我是刑警寧澤乡小,帶...
    沈念sama閱讀 34,270評(píng)論 4 329
  • 正文 年R本政府宣布阔加,位于F島的核電站,受9級(jí)特大地震影響劲件,放射性物質(zhì)發(fā)生泄漏掸哑。R本人自食惡果不足惜约急,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,867評(píng)論 3 312
  • 文/蒙蒙 一零远、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧厌蔽,春花似錦牵辣、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,734評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至戴卜,卻和暖如春逾条,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背投剥。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,961評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工师脂, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,297評(píng)論 2 360
  • 正文 我出身青樓吃警,卻偏偏與公主長(zhǎng)得像糕篇,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子酌心,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,472評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容