Android4.4 framework分析——ActivityManagerService的啟動和對Activity的管理

來源:互聯網
上載者:User

標籤:ams堆棧管理   activity管理   

本文主要介紹android4.4中ActivityManagerService的啟動和ActivityManagerService對Activity堆棧的管理。

一、ActivityManagerService的啟動

ActivityManagerService也是在SystemServer啟動的時候建立的,

<span style="font-size:18px;">class ServerThread {    .......   public void initAndLoop() {    ......    context = ActivityManagerService.main(factoryTest); //啟動AMS    .......    ActivityManagerService.setSystemProcess(); //向Service Manager註冊    .......   } }</span>
需要在一個新線程中初始化ActivityManagerService,ActivityManagerService用了單例模式。
<span style="font-size:18px;">    public static final Context main(int factoryTest) {        AThread thr = new AThread();        thr.start(); //啟動一個線程來啟動        synchronized (thr) {            while (thr.mService == null) {                try {                    thr.wait();//線程等待activitymanagerservice初始化完成                } catch (InterruptedException e) {                }            }        }        ActivityManagerService m = thr.mService;        mSelf = m;        ActivityThread at = ActivityThread.systemMain(); //啟動一個主線程        mSystemThread = at;        Context context = at.getSystemContext();        context.setTheme(android.R.style.Theme_Holo);         ......        m.mStackSupervisor = new ActivityStackSupervisor(m, context, thr.mLooper); //建立一個activity堆棧管理輔助類執行個體        .......        synchronized (thr) {            thr.mReady = true;            thr.notifyAll(); //activitymanagerservice啟動完成        }        m.startRunning(null, null, null, null);        return context;    }</span>

二、ActivityStackSupervisor和ActivityStack管理Activity的狀態

1.ActivityState

描述一個Activity可能經曆的所有狀態,定義在ActivityStack.java檔案中:

    enum ActivityState {        INITIALIZING, //正在初始化        RESUMED, //已經恢複        PAUSING, //正在暫停        PAUSED, //已經暫停        STOPPING, //正在停止        STOPPED, //已經停止        FINISHING, //正在完成        DESTROYING, //正在銷毀        DESTROYED //已經銷毀    }
 狀態變換圖:


    /**     * The back history of all previous (and possibly still     * running) activities.  It contains #TaskRecord objects.     */    private ArrayList<TaskRecord> mTaskHistory = new ArrayList<TaskRecord>();    /**     * Used for validating app tokens with window manager.     */    final ArrayList<TaskGroup> mValidateAppTokens = new ArrayList<TaskGroup>();    /**     * List of running activities, sorted by recent usage.     * The first entry in the list is the least recently used.     * It contains HistoryRecord objects.     */    final ArrayList<ActivityRecord> mLRUActivities = new ArrayList<ActivityRecord>();    /**     * Animations that for the current transition have requested not to     * be considered for the transition animation.     */    final ArrayList<ActivityRecord> mNoAnimActivities = new ArrayList<ActivityRecord>();    /**     * When we are in the process of pausing an activity, before starting the     * next one, this variable holds the activity that is currently being paused.     */    ActivityRecord mPausingActivity = null;    /**     * This is the last activity that we put into the paused state.  This is     * used to determine if we need to do an activity transition while sleeping,     * when we normally hold the top activity paused.     */    ActivityRecord mLastPausedActivity = null;    /**     * Activities that specify No History must be removed once the user navigates away from them.     * If the device goes to sleep with such an activity in the paused state then we save it here     * and finish it later if another activity replaces it on wakeup.     */    ActivityRecord mLastNoHistoryActivity = null;    /**     * Current activity that is resumed, or null if there is none.     */    ActivityRecord mResumedActivity = null;    /**     * This is the last activity that has been started.  It is only used to     * identify when multiple activities are started at once so that the user     * can be warned they may not be in the activity they think they are.     */    ActivityRecord mLastStartedActivity = null;
ActivityRecord變數的具體含義,可查看注釋。


2.記錄Activity的ArrayList和ActivityStack

    /** The stack containing the launcher app */    private ActivityStack mHomeStack;    /** The non-home stack currently receiving input or launching the next activity. If home is     * in front then mHomeStack overrides mFocusedStack.     * DO NOT ACCESS DIRECTLY - It may be null, use getFocusedStack() */    private ActivityStack mFocusedStack;    /** All the non-launcher stacks */    private ArrayList<ActivityStack> mStacks = new ArrayList<ActivityStack>();

mHomeStack : 只記錄存放Launcher和SystemUI(最近應用)的Task

mFocusedStack : 記錄所有非Launcher App的Task

mStacks : 這個ArrayList只存放mHomeStack和mFocusedStack,mHomeStack放在第0個位置

這個結果我是在用adb shell dumpsys activity命令查看而得知:

ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)  Stack #0:    Task id #1      TaskRecord{b22161f0 #1 A=com.android.launcher U=0 sz=1}      Intent { act=android.intent.action.MAIN cat=[android.intent.category.HOME] flg=0x10200000 cmp=com.android.launcher/com.android.launcher2.Launcher }        Hist #0: ActivityRecord{b2214570 u0 com.android.launcher/com.android.launcher2.Launcher t1}          Intent { act=android.intent.action.MAIN cat=[android.intent.category.HOME] flg=0x10000000 cmp=com.android.launcher/com.android.launcher2.Launcher }          ProcessRecord{b21df5c8 1402:com.android.launcher/u0a8}    Task id #3      TaskRecord{b2288fd0 #3 A=com.android.systemui U=0 sz=1}      Intent { act=com.android.systemui.recent.action.TOGGLE_RECENTS flg=0x10800000 cmp=com.android.systemui/.recent.RecentsActivity bnds=[132,331][296,476] (has extras) }        Hist #0: ActivityRecord{b22d5aa0 u0 com.android.systemui/.recent.RecentsActivity t3}          Intent { act=com.android.systemui.recent.action.TOGGLE_RECENTS flg=0x10800000 cmp=com.android.systemui/.recent.RecentsActivity bnds=[132,331][296,476] (has extras) }          ProcessRecord{b2169ac8 1313:com.android.systemui/u0a7}    Running activities (most recent first):      TaskRecord{b22161f0 #1 A=com.android.launcher U=0 sz=1}        Run #1: ActivityRecord{b2214570 u0 com.android.launcher/com.android.launcher2.Launcher t1}      TaskRecord{b2288fd0 #3 A=com.android.systemui U=0 sz=1}        Run #0: ActivityRecord{b22d5aa0 u0 com.android.systemui/.recent.RecentsActivity t3}  Stack #1:    Task id #4      TaskRecord{b21e57d0 #4 A=android.task.contacts U=0 sz=1}      Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.android.contacts/.activities.PeopleActivity }        Hist #0: ActivityRecord{b2281e68 u0 com.android.contacts/.activities.PeopleActivity t4}          Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.android.contacts/.activities.PeopleActivity bnds=[64,417][128,481] }          ProcessRecord{b22f66c0 1820:com.android.contacts/u0a2}    Task id #2      TaskRecord{b2229370 #2 A=com.android.dialer U=0 sz=1}      Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.android.dialer/.DialtactsActivity }        Hist #0: ActivityRecord{b223d3c8 u0 com.android.dialer/.DialtactsActivity t2}          Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.android.dialer/.DialtactsActivity bnds=[0,417][64,481] }          ProcessRecord{b2215d48 1569:com.android.dialer/u0a4}    Running activities (most recent first):      TaskRecord{b21e57d0 #4 A=android.task.contacts U=0 sz=1}        Run #1: ActivityRecord{b2281e68 u0 com.android.contacts/.activities.PeopleActivity t4}      TaskRecord{b2229370 #2 A=com.android.dialer U=0 sz=1}        Run #0: ActivityRecord{b223d3c8 u0 com.android.dialer/.DialtactsActivity t2}    mResumedActivity: ActivityRecord{b2281e68 u0 com.android.contacts/.activities.PeopleActivity t4}  mFocusedActivity: ActivityRecord{b2281e68 u0 com.android.contacts/.activities.PeopleActivity t4}  mDismissKeyguardOnNextActivity:false  mStackState=STACK_STATE_HOME_IN_BACK  mSleepTimeout: false  mCurTaskId: 4  mUserStackInFront: {}  Recent tasks:  * Recent #0: TaskRecord{b21e57d0 #4 A=android.task.contacts U=0 sz=1}  * Recent #1: TaskRecord{b22161f0 #1 A=com.android.launcher U=0 sz=1}  * Recent #2: TaskRecord{b2229370 #2 A=com.android.dialer U=0 sz=1}  * Recent #3: TaskRecord{b2288fd0 #3 A=com.android.systemui U=0 sz=1}

Stack #0 就是mHomeStack,裡面放了Launcher和SystemUI的task。

Stack #1 就是mFocusedStack,放了所有已經啟動的app的task。

這兩個就是mStacks裡面存放的。


3.現在看看mHomeStack和mFocusedStack是什麼時候被放入mStacks裡的?mHomeStack和mFocusedStack裡面的元素是在哪裡加入的?

     mHomeStack的初始化是在開機時,WindowManagerService建立完成後,ActivityManagerService設定WindowManagerService時,

            ActivityManagerService.self().setWindowManager(wm); //SystemServer.java中

    public void setWindowManager(WindowManagerService wm) { //<font size="4"><font size="4"><font size="4"><span style="font-size:18px;"><span style="font-size:18px;"><span style="font-size:18px;">ActivityManagerService</span></span></span></font></font>.java</font>中        mWindowManager = wm;        mStackSupervisor.setWindowManager(wm);        wm.createStack(HOME_STACK_ID, -1, StackBox.TASK_STACK_GOES_OVER, 1.0f);    }

    void setWindowManager(WindowManagerService wm) { //ActivityStackSupervisor.java中        mWindowManager = wm;        mHomeStack = new ActivityStack(mService, mContext, mLooper, HOME_STACK_ID);        mStacks.add(mHomeStack); //放在了第0個位置    }

Android4.4 framework分析——Launcher中啟動應用程式(startActivity)的過程      mFocusedStack存放的是應用程式的task,所以它的建立是在Activity啟動的時候,Activity的啟動過程可以參考step16,startActivityUncheckedLocked()中,

        if (r.resultTo == null && !addingToTask                && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {            targetStack = adjustStackFocus(r); //targetStack即目標Stack,r要加入的stack

    ActivityStack adjustStackFocus(ActivityRecord r) {        final TaskRecord task = r.task;        //r是否是應用程式的activity類型,或者r所屬task是應用程式task        //android定義區分了三種不同的activity類型        //static final int APPLICATION_ACTIVITY_TYPE = 0; //應用程式類型        //static final int HOME_ACTIVITY_TYPE = 1; //Launcher類型        //static final int RECENTS_ACTIVITY_TYPE = 2; //SystemUI的最近應用        if (r.isApplicationActivity() || (task != null && task.isApplicationTask())) {             if (task != null) {                if (mFocusedStack != task.stack) {                    if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,                            "adjustStackFocus: Setting focused stack to r=" + r + " task=" + task);                    mFocusedStack = task.stack;                } else {                    if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,                        "adjustStackFocus: Focused stack already=" + mFocusedStack);                }                return mFocusedStack;//app類型的activity每次都加入mFocusedStack            }            if (mFocusedStack != null) {                if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,                        "adjustStackFocus: Have a focused stack=" + mFocusedStack);                return mFocusedStack;//app類型的activity每次都加入mFocusedStack            }            for (int stackNdx = mStacks.size() - 1; stackNdx > 0; --stackNdx) {                ActivityStack stack = mStacks.get(stackNdx);                if (!stack.isHomeStack()) {                    if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,                            "adjustStackFocus: Setting focused stack=" + stack);                    mFocusedStack = stack;                    return mFocusedStack;//app類型的activity每次都加入mFocusedStack                }            }            // Time to create the first app stack for this user.            int stackId = mService.createStack(-1, HOME_STACK_ID, //啟動第一個app,需要建立一個stack,其他app建立時,前麵條件判斷將攔截住                StackBox.TASK_STACK_GOES_OVER, 1.0f);            if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, "adjustStackFocus: New stack r=" + r +                    " stackId=" + stackId);            mFocusedStack = getStack(stackId);            return mFocusedStack; //app類型的activity每次都加入mFocusedStack        }        return mHomeStack;    }

從上面這個方法看出,Launcher類型和最近應用類型的task將加入mHomeStack中,而其他應用類型的task加入mFocusedStack,

    public int createStack(int taskId, int relativeStackBoxId, int position, float weight) {        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,                "createStack()");        synchronized (this) {            long ident = Binder.clearCallingIdentity();            try {                int stackId = mStackSupervisor.createStack(); //看這裡                mWindowManager.createStack(stackId, relativeStackBoxId, position, weight);                if (taskId > 0) {                    moveTaskToStack(taskId, stackId, true);                }                return stackId;            } finally {                Binder.restoreCallingIdentity(ident);            }        }    }

    int createStack() {         while (true) {            if (++mLastStackId <= HOME_STACK_ID) {                mLastStackId = HOME_STACK_ID + 1;            }            if (getStack(mLastStackId) == null) {                break;            }        }        mStacks.add(new ActivityStack(mService, mContext, mLooper, mLastStackId)); //建立了一個Stack加入mStacks        return mLastStackId;    }
createStack()方法只有一次機會執行,即第一次運行app。

mStacks裡什麼情況下會出現第三或第四個元素,這個不知道,目前沒有發現這種情況。。。


未完待續,有不對的地方,請指正。



Android4.4 framework分析——ActivityManagerService的啟動和對Activity的管理

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.