天天看點

AMS分析--基于深入了解android(4)

final boolean realStartActivityLocked(ActivityRecord r,
            ProcessRecord app, boolean andResume, boolean checkConfig)
            throws RemoteException {
        r.startFreezingScreenLocked(app, );//當機螢幕
        if (false) Slog.d(TAG, "realStartActivity: setting app visibility true");
        mWindowManager.setAppVisibility(r.appToken, true);//設定app的r可見

        // schedule launch ticks to collect information about slow apps.
        r.startLaunchTickingLocked();//列印啟動日志

        // Have the window manager re-evaluate the orientation of
        // the screen based on the new activity order.  Note that
        // as a result of this, it can call back into the activity
        // manager with a new orientation.  We don't care about that,
        // because the activity is not currently running so we are
        // just restarting it anyway.
        if (checkConfig) {
            Configuration config = mWindowManager.updateOrientationFromAppTokens(
                    mService.mConfiguration,
                    r.mayFreezeScreenLocked(app) ? r.appToken : null);
            //處理Config發生變化的情況
            mService.updateConfigurationLocked(config, r, false, false);
        }

        r.app = app;
        app.waitingToKill = null;
        r.launchCount++;
        r.lastLaunchTime = SystemClock.uptimeMillis();

        /// M: AMS log enhancement @{
        if (localLOGV) Slog.v(TAG, "ACT-Launching: " + r);
        /// @}

        int idx = app.activities.indexOf(r);
        //将ActivityRecord加到ProcessRecord的activities中儲存
        if (idx < ) {
            app.activities.add(r);
        }
        mService.updateLruProcessLocked(app, true, null);
        mService.updateOomAdjLocked();
        //更新程序的排程優先級等,以後再分析該函數

        final ActivityStack stack = r.task.stack;
        try {
            if (app.thread == null) {
                throw new RemoteException();
            }
            List<ResultInfo> results = null;
            List<Intent> newIntents = null;
            if (andResume) {
                results = r.results;
                newIntents = r.newIntents;
            }
            if (DEBUG_SWITCH) Slog.v(TAG, "Launching: " + r
                    + " icicle=" + r.icicle
                    + " with results=" + results + " newIntents=" + newIntents
                    + " andResume=" + andResume);
            if (andResume) {
                EventLog.writeEvent(EventLogTags.AM_RESTART_ACTIVITY,
                        r.userId, System.identityHashCode(r),
                        r.task.taskId, r.shortComponentName);
                /// M: AMS log enhancement @{
                if (!ActivityManagerService.IS_USER_BUILD)
                   Slog.d(TAG, "ACT-AM_RESTART_ACTIVITY " + r + " Task:" + r.task.taskId);
                /// @}
            }
            if (r.isHomeActivity() && r.isNotResolverActivity()) {//是home程式且不是ResolverActivity
                // Home process is the root process of the task.
                mService.mHomeProcess = r.task.mActivities.get().app;
            }
            mService.ensurePackageDexOpt(r.intent.getComponent().getPackageName());
            對該APK做dex優化
            r.sleeping = false;
            r.forceNewConfig = false;
            mService.showAskCompatModeDialogLocked(r);
            r.compat = mService.compatibilityInfoForPackageLocked(r.info.applicationInfo);
            String profileFile = null;
            ParcelFileDescriptor profileFd = null;
            boolean profileAutoStop = false;
            if (mService.mProfileApp != null && mService.mProfileApp.equals(app.processName)) {
                if (mService.mProfileProc == null || mService.mProfileProc == app) {
                    mService.mProfileProc = app;
                    profileFile = mService.mProfileFile;
                    profileFd = mService.mProfileFd;
                    profileAutoStop = mService.mAutoStopProfiler;
                }
            }
            app.hasShownUi = true;
            app.pendingUiClean = true;
            if (profileFd != null) {
                try {
                    profileFd = profileFd.dup();
                } catch (IOException e) {
                    if (profileFd != null) {
                        try {
                            profileFd.close();
                        } catch (IOException o) {
                        }
                        profileFd = null;
                    }
                }
            }
            app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_TOP);//設定程序為目前Activity所屬程序所有者

            mService.logAppLaunchTime(TAG, "scheduleLaunchActivity -> ActivityThread"); /// M: It's for debugging App Launch time
            //通知應用程序啟動Activity
            app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
                    System.identityHashCode(r), r.info,
                    new Configuration(mService.mConfiguration), r.compat,
                    app.repProcState, r.icicle, results, newIntents, !andResume,
                    mService.isNextTransitionForward(), profileFile, profileFd,
                    profileAutoStop);

            if ((app.info.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != ) {
                // This may be a heavy-weight process!  Note that the package
                // manager will ensure that only activity can run in the main
                // process of the .apk, which is the only thing that will be
                // considered heavy-weight.
                if (app.processName.equals(app.info.packageName)) {
                    if (mService.mHeavyWeightProcess != null
                            && mService.mHeavyWeightProcess != app) {
                        Slog.w(TAG, "Starting new heavy weight process " + app
                                + " when already running "
                                + mService.mHeavyWeightProcess);
                    }
                    mService.mHeavyWeightProcess = app;
                    Message msg = mService.mHandler.obtainMessage(
                            ActivityManagerService.POST_HEAVY_NOTIFICATION_MSG);
                    msg.obj = r;
                    mService.mHandler.sendMessage(msg);
                }
            }

        } catch (RemoteException e) {
            if (r.launchFailed) {
                // This is the second time we failed -- finish activity
                // and give up.
                Slog.e(TAG, "Second failure launching "
                      + r.intent.getComponent().flattenToShortString()
                      + ", giving up", e);
                mService.appDiedLocked(app, app.pid, app.thread);
                stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
                        "2nd-crash", false);
                return false;
            }

            /// M: fix google issue, add to prevent process starting repeatly
            /// If AP is in 2nd crash, we will stop trying to start AP process. @{
            r.launchFailed = true;
            /// @}

            // This is the first time we failed -- restart process and
            // retry.
            app.activities.remove(r);
            throw e;
        }

        r.launchFailed = false;
        if (stack.updateLRUListLocked(r)) {//更新oodm 程序優先級
            Slog.w(TAG, "Activity " + r
                  + " being launched, but already in LRU list");
        }

        if (andResume) {
            // As part of the process of launching, ActivityThread also performs
            // a resume.
            stack.minimalResumeActivityLocked(r);//完成 Activity 啟動
        } else {
            // This activity is not starting in the resumed state... which
            // should look like we asked it to pause+stop (but remain visible),
            // and it has done so and reported back the current icicle and
            // other state.
            if (DEBUG_STATES) Slog.v(TAG, "Moving to STOPPED: " + r
                    + " (starting in stopped state)");
            r.state = ActivityState.STOPPED;
            r.stopped = true;
        }

        // Launch the new version setup screen if needed.  We do this -after-
        // launching the initial activity (that is, home), so that it can have
        // a chance to initialize itself while in the background, making the
        // switch back to it faster and look better.
        if (isFrontStack(stack)) {
            mService.startSetupActivityLocked();//是否更新  ui顯示
        }

        return true;
    }
           

調用 ProcessRecord.thread ( ActivityThread 類型)的 scheduleLaunchActivity() 通知應用的主程序啟動 Activity :

AMS通過realStartActivityLocked函數來排程應用程式程序啟動一個Activity,參數r為即将啟動的Activity在AMS服務中的描述符,參數app為Activity運作所在的應用程式程序在AMS服務中的描述符。函數通過IApplicationThread代理對象ApplicationThreadProxy通知應用程式程序啟動r對應的Activity,應用程式程序完成Activity的加載等準備工作後,AMS最後啟動該Activity。啟動Activity的建立等工作是在應用程式程序中完成的,AMS是通過IApplicationThread接口和應用程式程序通信的。r.appToken 在AMS服務端的類型為Token,是IApplicationToken的Binder本地對象。

public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
                ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,
                int procState, Bundle state, List<ResultInfo> pendingResults,
                List<Intent> pendingNewIntents, boolean notResumed, boolean isForward,
                String profileName, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {

            updateProcessState(procState, false);

            ActivityClientRecord r = new ActivityClientRecord();

            r.token = token;
            r.ident = ident;
            r.intent = intent;
            r.activityInfo = info;
            r.compatInfo = compatInfo;
            r.state = state;

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

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

            r.profileFile = profileName;
            r.profileFd = profileFd;
            r.autoStopProfiler = autoStopProfiler;

            updatePendingConfiguration(curConfig);

            sendMessage(H.LAUNCH_ACTIVITY, r);
        }
           

參數token從AMS服務端經過Binder傳輸到應用程式程序後,變為IApplicationToken的Binder代理對象,類型為IApplicationToken.Proxy,這是因為AMS和應用程式運作在不同的程序中。

AMS分析--基于深入了解android(4)

通過queueOrSendMessage函數将Binder跨程序調用轉換為應用程式程序中的異步消息處理

上述代碼最後調用到

public void handleMessage(Message msg) {
    ......
      switch (msg.what) {
                case LAUNCH_ACTIVITY: {
                    ActivityClientRecord r = (ActivityClientRecord)msg.obj;
                    //ActivityClientRecord 代表着在應用程序中的一個Activity
                    r.packageInfo = getPackageInfoNoCheck(
                    r.activityInfo.applicationInfo, r.compatInfo);
                    handleLaunchActivity(r, null);  
}
           

r.packageInfo = getPackageInfoNoCheck(

r.activityInfo.applicationInfo, r.compatInfo) ->

getPackageInfo(ai, compatInfo, null, false, true) ->

new LoadedApk(this, aInfo, compatInfo, this, baseLoader,

securityViolation, includeCode &&

(aInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0)

獲得目前 Activity的LoadedApk對象。

public LoadedApk(ActivityThread activityThread, String name,
            Context systemContext, ApplicationInfo info, CompatibilityInfo compatInfo) {
        mActivityThread = activityThread;
        mApplicationInfo = info != null ? info : new ApplicationInfo();
        mApplicationInfo.packageName = name;
        mPackageName = name;
        mAppDir = null;
        mResDir = null;
        mSharedLibraries = null;
        mDataDir = null;
        mDataDirFile = null;
        mLibDir = null;
        mBaseClassLoader = null;
        mSecurityViolation = false;
        mIncludeCode = true;
        mClassLoader = systemContext.getClassLoader();
        mResources = systemContext.getResources();
        mDisplayAdjustments.setCompatibilityInfo(compatInfo);
    }
           
LoadedApk類記錄了Activity運作所在的ActivityThread、Activity所在的應用程式資訊、Activity的包名、Activity的資源路徑、Activity的庫路徑、Activity的資料存儲路徑、類加載器和應用程式所使用的資源等資訊
           
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        // System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")");

        ActivityInfo aInfo = r.activityInfo;
        if (r.packageInfo == null) { //如果 LoadedApk 為null,重新擷取LoadedApk
            r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
                    Context.CONTEXT_INCLUDE_CODE);
        }

        ComponentName component = r.intent.getComponent();//擷取Activity的 ComponentName
        if (component == null) {
            component = r.intent.resolveActivity(
                mInitialApplication.getPackageManager());
            r.intent.setComponent(component);
        }

        if (r.activityInfo.targetActivity != null) {
             //packageName為啟動Activity的包名,targetActivity為Activity的類名
            component = new ComponentName(r.activityInfo.packageName,
                    r.activityInfo.targetActivity);
        }

        Activity activity = null;
        try {
             //通過類反射方式加載即将啟動的Activity
              //利用Class loader和ComponentName對象搭配  
            //mInstrumentation.newActivity函數産生一個新的activity對象.  
            java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);
            StrictMode.incrementExpectedActivityCount(activity.getClass());
            r.intent.setExtrasClassLoader(cl);
            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);
            }
        }

        try {
             //通過單例模式為應用程式程序建立Application對象
            Application app = r.packageInfo.makeApplication(false, mInstrumentation);

            if (localLOGV) Slog.v(TAG, "Performing launch of " + r);
            if (localLOGV || mIsUserBuild) Slog.v(
                    TAG, r + ": app=" + app
                    + ", appName=" + app.getPackageName()
                    + ", pkg=" + r.packageInfo.getPackageName()
                    + ", comp=" + r.intent.getComponent().toShortString()
                    + ", dir=" + r.packageInfo.getAppDir());

            if (activity != null) {
                 //為目前Activity建立上下文對象ContextImpl
                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和上下文ContextImpl、Application綁定
                activity.attach(appContext, this, getInstrumentation(), r.token,
                        r.ident, app, r.intent, r.activityInfo, title, r.parent,
                        r.embeddedID, r.lastNonConfigurationInstances, config);

                if (customIntent != null) {
                    activity.mIntent = customIntent;
                }
                //設定activity的參數intent設定跟背景主題設定  
                r.lastNonConfigurationInstances = null;
                activity.mStartedActivity = false;
                int theme = r.activityInfo.getThemeResource();
                if (theme != ) {
                    activity.setTheme(theme);
                }

                activity.mCalled = false;
                 //調用Activity的OnCreate函數
                mInstrumentation.callActivityOnCreate(activity, r.state);
                if (!activity.mCalled) {
                    throw new SuperNotCalledException(
                        "Activity " + r.intent.getComponent().toShortString() +
                        " did not call through to super.onCreate()");
                }
                //将Activity儲存到ActivityClientRecord中,ActivityClientRecord為Activity在應用程式程序中的描述符
                r.activity = activity;
                r.stopped = true;
                if (!r.activity.mFinished) {
                    activity.performStart();
                    r.stopped = false;
                }
                if (!r.activity.mFinished) {//mFinished 表示
                    if (r.state != null) {
                        //在activity被殺掉之前調用儲存每個執行個體的狀态,以保證該狀态可以在onCreate(Bundle)或者onRestoreInstanceState(Bundle) 
                        //(傳入的Bundle參數是由onSaveInstanceState封裝好的)中恢複。這個方法在一個activity被殺死前調用
                        //,當該activity在将來某個時刻回來時可以恢複其先前狀态。 
                        //最終會調用onRestoreInstanceState 方法 ,将 activity恢複其先前狀态
                        mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
                    }
                }
                if (!r.activity.mFinished) {
                    activity.mCalled = false;
                    mInstrumentation.callActivityOnPostCreate(activity, r.state);
                    if (!activity.mCalled) {
                        throw new SuperNotCalledException(
                            "Activity " + r.intent.getComponent().toShortString() +
                            " did not call through to super.onPostCreate()");
                    }
                }
            }
            r.paused = true;
            //ActivityThread的成員變量mActivities儲存了目前應用程式程序中的所有Activity的描述符
        mActivities.put(r.token, r);
            mActivities.put(r.token, r);

        } catch (SuperNotCalledException e) {
            throw e;

        } catch (Exception e) {
            if (!mInstrumentation.onException(activity, e)) {
                throw new RuntimeException(
                    "Unable to start activity " + component
                    + ": " + e.toString(), e);
            }
        }

        return activity;
    }
           

在該函數中,首先通過PMS服務查找到即将啟動的Activity的包名資訊,然後通過類反射方式建立一個該Activity執行個體,同時為應用程式啟動的每一個Activity建立一個LoadedApk執行個體對象,應用程式程序中建立的所有LoadedApk對象儲存在ActivityThread的成員變量mPackages中。接着通過LoadedApk對象的makeApplication函數,使用單例模式建立Application對象,是以在android應用程式程序中有且隻有一個Application執行個體。然後為目前啟動的Activity建立一個ContextImpl上下文對象,并初始化該上下文,到此我們可以知道,啟動一個Activity需要以下對象:

1) XXActivity對象,需要啟動的Activity;

2) LoadedApk對象,每個啟動的Activity都擁有屬于自身的LoadedApk對象;

3) ContextImpl對象,每個啟動的Activity都擁有屬于自身的ContextImpl對象;

4) Application對象,應用程式程序中有且隻有一個執行個體,和Activity是一對多的關系;

public final ActivityClientRecord performResumeActivity(IBinder token,
            boolean clearHide) {
        ActivityClientRecord r = mActivities.get(token);//找出目前要啟動的Activities
        if (localLOGV || mIsUserBuild) Slog.v(TAG, "Performing resume of " + r
                + " finished=" + ((r != null && r.activity != null)
                        ? r.activity.mFinished : null));
        if (r != null && !r.activity.mFinished) {
            if (clearHide) {
                r.hideForNow = false;
                r.activity.mStartedActivity = false;
            }
            try {
                r.activity.mFragments.noteStateNotSaved();
                if (r.pendingIntents != null) {
                    deliverNewIntents(r, r.pendingIntents);//當在singleTask 或者singleTop模式下,系統中隻會存在一個
                    //Activity執行個體,是以當我們要啟動這個執行個體的時候,如果發現系統中已經存在activity,就會執行onNewIntent
                    r.pendingIntents = null;
                }
                if (r.pendingResults != null) {
                    deliverResults(r, r.pendingResults);
                    r.pendingResults = null;
                }
                r.activity.performResume();
                //會先執行 performRestart -> activity.onRestart()
                 // 接着 -> callActivityOnResume-> activity.onResume

                EventLog.writeEvent(LOG_ON_RESUME_CALLED,
                        UserHandle.myUserId(), r.activity.getComponentName().getClassName());
                /// M: ActivityThread log enhancement @{
                if(!mIsUserBuild)
                   Slog.d(TAG, "ACT-AM_ON_RESUME_CALLED " + r);
                /// @}

                r.paused = false;
                r.stopped = false;
                r.state = null;
            } catch (Exception e) {
                if (!mInstrumentation.onException(r.activity, e)) {
                    throw new RuntimeException(
                        "Unable to resume activity "
                        + r.intent.getComponent().toShortString()
                        + ": " + e.toString(), e);
                }
            }
        }
        return r;
    }
           

調用activity.performResume()方法,在activity.performResume()中會預設先調用performRestart(),performRestart()的作用是先檢查activity是否處于stopped狀态,如果是則調用performRestart()再調用performStart()。最後再響應activity的生命周期方法onResume()。

是以,新打開一個activity的響應流程是:

onCreate()->onStart()->onResume()

而傳回一個背景activity的響應流程是:

onRestart()->onStart()->onResume()

final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward,
            boolean reallyResume) {
if (r.window == null && !a.mFinished && willBeVisible) {
                //獲得為目前Activity建立的視窗PhoneWindow對象
                r.window = r.activity.getWindow();
                 //擷取為視窗建立的視圖DecorView對象
                View decor = r.window.getDecorView();
                decor.setVisibility(View.INVISIBLE);
                 //在attach函數中就為目前Activity建立了WindowManager對象
                ViewManager wm = a.getWindowManager();
                WindowManager.LayoutParams l = r.window.getAttributes();
                 //得到該視圖對象的布局參數
                a.mDecor = decor;
                l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
                l.softInputMode |= forwardBit;
                if (a.mVisibleFromClient) {
                    a.mWindowAdded = true;
                     //将建立的視圖對象DecorView添加到Activity的視窗管理器中
                    wm.addView(decor, l);
                }
                ......
                 if (r.activity.mVisibleFromClient) {
                        ViewManager wm = a.getWindowManager();
                        View decor = r.window.getDecorView();
                        wm.updateViewLayout(decor, l);
                        //将目前Activity的視圖顯示出來
                    }
                    ...
                      Looper.myQueue().addIdleHandler(new Idler());
                //一是調用方法finishUserBoot()把狀态還是STATE_BOOTING的使用者切換到STATE_RUNNING狀态
                //,同時發送廣播ACTION_BOOT_COMPLETED給該使用者,表示使用者啟動結束。另一件工作是停止多餘的使用者

           
final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,
            Configuration config) {
        if (localLOGV) Slog.v(TAG, "Activity idle: " + token);

        /// M: PerfBoost @{
        if (mIsPerfBoostEnable) {
            PerfService.nativePerfBoostDisable(PerfService.SCN_APP_SWITCH);
            mIsPerfBoostEnable = false;
        }
        /// @}

        ArrayList<ActivityRecord> stops = null;
        ArrayList<ActivityRecord> finishes = null;
        ArrayList<UserStartedState> startingUsers = null;
        int NS = ;
        int NF = ;
        IApplicationThread sendThumbnail = null;
        boolean booting = false;
        boolean enableScreen = false;
        boolean activityRemoved = false;

        ActivityRecord r = ActivityRecord.forToken(token);//找到目前的 ActivityRecord
        if (r != null) {
            if (DEBUG_IDLE) Slog.d(TAG, "activityIdleInternalLocked: Callers=" +
                    Debug.getCallers());
            mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);//移除IDLE_TIMEOUT_MSG 消息
            r.finishLaunchTickingLocked();
            if (fromTimeout) {
                reportActivityLaunchedLocked(fromTimeout, r, -, -);
            }

            // This is a hack to semi-deal with a race condition
            // in the client where it can be constructed with a
            // newer configuration from when we asked it to launch.
            // We'll update with whatever configuration it now says
            // it used to launch.
            if (config != null) {
                r.configuration = config;
            }

            // We are now idle.  If someone is waiting for a thumbnail from
            // us, we can now deliver.
            r.idle = true;//目前我們已經進入idle模式。并且已經移除IDLE_TIMEOUT_MSG,是以為 true

            if (r.thumbnailNeeded && r.app != null && r.app.thread != null) {
                sendThumbnail = r.app.thread;
                r.thumbnailNeeded = false;
            }

            //Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout);
            if (!mService.mBooted && isFrontStack(r.task.stack)) {
                mService.mBooted = true;
                enableScreen = true;
            }
        }

        if (allResumedActivitiesIdle()) {//是以此處 内部我們判斷r.idle為true
            if (r != null) {
                mService.scheduleAppGcsLocked();//知所有進行中的任務進行垃圾回收
            }
                /*
                   mLaunchingActivity是一個WakeLock,它能防止在操作Activity過程中掉電,同時
                   這個WakeLock又不能長時間使用,否則有可能耗費過多電量。是以,系統設定了一個逾時
                   處理消息LAUNCH_TIMEOUT_MSG,逾時時間為10秒。一旦目标Activity啟動成功,
                   就需要需要釋放 WakeLock
                */

            if (mLaunchingActivity.isHeld()) {
                mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
                if (VALIDATE_WAKE_LOCK_CALLER &&
                        Binder.getCallingUid() != Process.myUid()) {
                    throw new IllegalStateException("Calling must be system uid");
                }
                mLaunchingActivity.release();
            }
            ensureActivitiesVisibleLocked(null, );
        }

        // Atomically retrieve all of the other things to do.
        stops = processStoppingActivitiesLocked(true);// 得到因本次啟動而被 pause 的 Activity
        NS = stops != null ? stops.size() : ;
        if ((NF=mFinishingActivities.size()) > ) {
            finishes = new ArrayList<ActivityRecord>(mFinishingActivities);
            mFinishingActivities.clear();
        }

        final ArrayList<ActivityRecord> thumbnails;
        final int NT = mCancelledThumbnails.size();
        if (NT > ) {
            thumbnails = new ArrayList<ActivityRecord>(mCancelledThumbnails);
            mCancelledThumbnails.clear();
        } else {
            thumbnails = null;
        }

        if (isFrontStack(mHomeStack)) {
            booting = mService.mBooting;
            mService.mBooting = false;
        }

        if (mStartingUsers.size() > ) {
            startingUsers = new ArrayList<UserStartedState>(mStartingUsers);
            mStartingUsers.clear();
        }

        // Perform the following actions from unsynchronized state.
        final IApplicationThread thumbnailThread = sendThumbnail;
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                if (thumbnailThread != null) {
                    try {
                        thumbnailThread.requestThumbnail(token);
                    } catch (Exception e) {
                        Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
                        mService.sendPendingThumbnail(null, token, null, null, true);
                    }
                }

                // Report back to any thumbnail receivers.
                for (int i = ; i < NT; i++) {
                    ActivityRecord r = thumbnails.get(i);
                    mService.sendPendingThumbnail(r, null, null, null, true);
                }
            }
        });

        // Stop any activities that are scheduled to do so but have been
        // waiting for the next one to start.
        for (int i = ; i < NS; i++) {
            r = stops.get(i);
            final ActivityStack stack = r.task.stack;
            if (r.finishing) {
                stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false);
                // 如果被暫停的Activity處于finishing狀态(例如Activity在其onStop中調用了finish函數),則調用finishCurrentActivityLocked
            } else {
                stack.stopActivityLocked(r);
            }
        }

        // Finish any activities that are scheduled to do so but have been
        // waiting for the next one to start.
        for (int i = ; i < NF; i++) {
            r = finishes.get(i);
            activityRemoved |= r.task.stack.destroyActivityLocked(r, true, false, "finish-idle");
        }

        if (booting) {//如果是系統開機啟動桌面。此時啟動完成發廣播 ACTION_BOOT_COMPLETED
            mService.finishBooting();
        } else if (startingUsers != null) {
            for (int i = ; i < startingUsers.size(); i++) {
                mService.finishUserSwitch(startingUsers.get(i));
            }
        }

        mService.trimApplications();
        //dump();
        //mWindowManager.dump();

        if (enableScreen) {
            mService.enableScreenAfterBoot();
        }

        if (activityRemoved) {
            resumeTopActivitiesLocked();
        }

        return r;
    }
           

在startPausingLocked()時會将要paused的ActivityRecord儲存在mPausingActivity中,當pause成功後會調用activityPausedLocked()函數做後續處理,在這個函數中會将mPausingActivity重置為null

final void startPausingLocked(boolean userLeaving, boolean uiSleeping) {
        if (mPausingActivity != null) {
            //如果要pause一個Activity時,已經有一個Activity在pause還未完成 
            //(pause完成的話mPausingActivity 為null),那麼抛出一個異常。
            Slog.e(TAG, "Trying to pause when pause is already pending for "
                  + mPausingActivity, new RuntimeException("here").fillInStackTrace());
        }
        ActivityRecord prev = mResumedActivity;//儲存正在顯示的app
           //mResumedActivity中儲存的是目前resume的Activity, 
          // pause的對象肯定是目前的resume的Activity,如果目前沒有resume對象, 
          //這種情況也就是系統啟動第一個Activity才有的情況,此時就直接resume Activity棧中的頂層Activity。  
        if (prev == null) {
            Slog.e(TAG, "Trying to pause when nothing is resumed",
                    new RuntimeException("here").fillInStackTrace());
            mStackSupervisor.resumeTopActivitiesLocked();
            return;
        }
        if (DEBUG_STATES) Slog.v(TAG, "Moving to PAUSING: " + prev);
        else if (DEBUG_PAUSE) Slog.v(TAG, "Start pausing: " + prev);
         //目前resume的Activity要被pause掉了,那麼mResumedActivity必然要重置為null了?
         // 同時mPausingActivity指向目前resumed的Activity。 
        mResumedActivity = null;
        mPausingActivity = prev;
        mLastPausedActivity = prev;
        mLastNoHistoryActivity = (prev.intent.getFlags() & Intent.FLAG_ACTIVITY_NO_HISTORY) != 
                || (prev.info.flags & ActivityInfo.FLAG_NO_HISTORY) !=  ? prev : null;
        prev.state = ActivityState.PAUSING;
        prev.task.touchActiveTime();
        clearLaunchTime(prev);

        /// M: Add for launch time enhancement @{
        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "amScreenCapture");
        if (!prev.isHomeActivity()) {
            prev.updateThumbnail(screenshotActivities(prev), null);
        }
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        /// @}

        stopFullyDrawnTraceIfNeeded();

        mService.updateCpuStats();

        if (prev.app != null && prev.app.thread != null) {
            if (DEBUG_PAUSE) Slog.v(TAG, "Enqueueing pending pause: " + prev);
            try {
                EventLog.writeEvent(EventLogTags.AM_PAUSE_ACTIVITY,
                        prev.userId, System.identityHashCode(prev),
                        prev.shortComponentName);
                /// M: AMS log enhancement @{
                if (!ActivityManagerService.IS_USER_BUILD)
                    Slog.d(TAG, "ACT-AM_PAUSE_ACTIVITY " + prev );
                /// @}
                mService.updateUsageStats(prev, false);
                 //調用目前Activity所在程序的schedulePauseActivity函數
                prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,
                        userLeaving, prev.configChangeFlags);
            } catch (Exception e) {
                // Ignore exception, if process died other code will cleanup.
                Slog.w(TAG, "Exception thrown during pause", e);
                mPausingActivity = null;
                mLastPausedActivity = null;
                mLastNoHistoryActivity = null;
            }
        } else {
            mPausingActivity = null;
            mLastPausedActivity = null;
            mLastNoHistoryActivity = null;
        }

        // If we are not going to sleep, we want to ensure the device is
        // awake until the next activity is started.
        if (!mService.isSleepingOrShuttingDown()) {
            mStackSupervisor.acquireLaunchWakelock();
            //擷取一個喚醒鎖,防止系統睡眠,擷取喚醒鎖時要注意釋放
        }

        if (mPausingActivity != null) {
            // 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();//暫停按鍵下發通道,直到新的activity起來
            } else {
                if (DEBUG_PAUSE) Slog.v(TAG, "Key dispatch not paused for screen off");
            }

            // Schedule a pause timeout in case the app doesn't respond.
            // We don't give it much time because this directly impacts the
            // responsiveness seen by the user.
            Message msg = mHandler.obtainMessage(PAUSE_TIMEOUT_MSG);
            msg.obj = prev;
            prev.pauseTime = SystemClock.uptimeMillis();
            mHandler.sendMessageDelayed(msg, PAUSE_TIMEOUT);
            //設定逾時500ms,告訴應用盡快完成相關操作
            //⑨post一個PAUSE_TIMEOUT_MSG消息,為什麼要post這麼個消息
            //,是因為如果無法完成paused前一個Activity,那麼就無法start下一個Activity
            //,這個逾時消息是防止異常導緻無法及時start下一個Activity,在逾時消息處理函數中肯定有start next Activity的邏輯。  
            if (DEBUG_PAUSE) Slog.v(TAG, "Waiting for pause to complete...");
        } else {
            // This activity failed to schedule the
            // pause, so just treat it as being paused now.
            if (DEBUG_PAUSE) Slog.v(TAG, "Activity not running, resuming next.");
            mStackSupervisor.getFocusedStack().resumeTopActivityLocked(null);
        }
    }
           

startPausingLocked将調用應用程序的schedulePauseActivity函數,并設定500毫秒的逾時時間,是以應用程序需盡快完成相關處理。和scheduleLaunchActivity一樣,schedulePauseActivity将向ActivityThread主線程發送PAUSE_ACTIVITY消息,最終該消息由handlePauseActivity來處理。

private void handlePauseActivity(IBinder token, boolean finished,
            boolean userLeaving, int configChanges) {
        ActivityClientRecord r = mActivities.get(token);
        if (r != null) {
            //Slog.v(TAG, "userLeaving=" + userLeaving + " handling pause of " + r);
            if (userLeaving) {
                performUserLeavingActivity(r);//告訴使用者要離開目前activity,會調用onUserLeaveHint函數
            }

            r.activity.mConfigChangeFlags |= configChanges;
            performPauseActivity(token, finished, r.isPreHoneycomb());   //調用Activity的onPause函數

            // Make sure any pending writes are now committed.
            if (r.isPreHoneycomb()) {
                QueuedWork.waitToFinish();
            }

            // Tell the activity manager we have paused.
            try {
                ActivityManagerNative.getDefault().activityPaused(token);
            } catch (RemoteException ex) {
            }
        }
    }
           
final void activityPausedLocked(IBinder token, boolean timeout) {
        if (DEBUG_PAUSE) Slog.v(
            TAG, "Activity paused: token=" + token + ", timeout=" + timeout);
        /// M: AMS log enhancement @{
        if (!ActivityManagerService.IS_USER_BUILD)
            Slog.d(TAG, "ACT-paused: token=" + token + ", timeout=" + timeout);
        /// @}

        final ActivityRecord r = isInStackLocked(token);
        if (r != null) {
             //從消息隊列中撤銷PAUSE_TIMEOUT_MSG消息
            mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
            if (mPausingActivity == r) {
                if (DEBUG_STATES) Slog.v(TAG, "Moving to PAUSED: " + r
                        + (timeout ? " (due to timeout)" : " (pause complete)"));
                r.state = ActivityState.PAUSED;//設定 ActivityRecord 狀态
                completePauseLocked();//完成本次 暫停
           
private void completePauseLocked() {
        ActivityRecord prev = mPausingActivity;
        if (DEBUG_PAUSE) Slog.v(TAG, "Complete pause: " + prev);

        if (prev != null) {
            if (prev.finishing) {
                if (DEBUG_PAUSE) Slog.v(TAG, "Executing finish of activity: " + prev);
                prev = finishCurrentActivityLocked(prev, FINISH_AFTER_VISIBLE, false);//結束這個 ActivityRecord
            } else if (prev.app != null) {
                if (DEBUG_PAUSE) Slog.v(TAG, "Enqueueing pending stop: " + prev);
                if (prev.waitingVisible) {
                    prev.waitingVisible = false;//因為此Activity要暫停,是以不在等待可見。隻有要顯示Activity 的waitingVisible為true
                    mStackSupervisor.mWaitingVisibleActivities.remove(prev);
                    if (DEBUG_SWITCH || DEBUG_PAUSE) Slog.v(
                            TAG, "Complete pause, no longer waiting: " + prev);
                }
                if (prev.configDestroy) {
                    destroyActivityLocked(prev, true, false, "pause-config");
                } else {
                    mStackSupervisor.mStoppingActivities.add(prev);
                    if (mStackSupervisor.mStoppingActivities.size() >  ||
                            prev.frontOfTask && mTaskHistory.size() <= ) {
                        if (DEBUG_PAUSE) Slog.v(TAG, "To many pending stops, forcing idle");
                        mStackSupervisor.scheduleIdleLocked();
                        //如果被暫停的activity超過3個或者 目前activity是root activity且目前task是最後一個task
                        if (!ActivityManagerService.IS_USER_BUILD)
                            Slog.d(TAG, "ACT-IDLE_NOW_MSG from completePauseLocked for mStoppingActivities.size() > 3");
                        /// @}
                    } else {
                        mStackSupervisor.checkReadyForSleepLocked();
                    }
                }
            } else {
                if (DEBUG_PAUSE) Slog.v(TAG, "App died during pause, not stopping: " + prev);
                prev = null;
            }
            mPausingActivity = null;
        }

        final ActivityStack topStack = mStackSupervisor.getFocusedStack();
        if (!mService.isSleepingOrShuttingDown()) {//如果系統不是在将要睡眠和關閉
            mStackSupervisor.resumeTopActivitiesLocked(topStack, prev, null);//啟動在棧頂的Activity
        } else {
            mStackSupervisor.checkReadyForSleepLocked();
            ActivityRecord top = topStack.topRunningActivityLocked(null);//啟動在棧頂的Activity
            if (top == null || (prev != null && top != prev)) {

                mStackSupervisor.resumeTopActivitiesLocked(topStack, null, null);
            }
        }

        if (prev != null) {
            /// M: it's to avoid deadlock in AMS/WMS, Ref: ALPS00231742 @{
            //prev.resumeKeyDispatchingLocked();
            new myThread(prev).start();
            /// @}

            if (prev.app != null && prev.cpuTimeAtResume > 
                    && mService.mBatteryStatsService.isOnBattery()) {
                long diff;
                synchronized (mService.mProcessCpuThread) {
                    diff = mService.mProcessCpuTracker.getCpuTimeForPid(prev.app.pid)
                            - prev.cpuTimeAtResume;
                }
                if (diff > ) {
                    BatteryStatsImpl bsi = mService.mBatteryStatsService.getActiveStatistics();
                    synchronized (bsi) {
                        BatteryStatsImpl.Uid.Proc ps =
                                bsi.getProcessStatsLocked(prev.info.applicationInfo.uid,
                                        prev.info.packageName);
                        if (ps != null) {
                            ps.addForegroundTimeLocked(diff);
                        }
                    }
                }
            }
            prev.cpuTimeAtResume = ; // reset it
        }
    }