標籤: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的管理