您的位置:首页 > 其它

ActivityManagerService的启动和ActivityManagerService对Activity堆栈的管理

2015-05-26 10:53 369 查看
原文地址:http://blog.csdn.net/canghai1129/article/details/41392247

本文主要介绍android4.4中ActivityManagerService的启动和ActivityManagerService对Activity堆栈的管理。

一、ActivityManagerService的启动

ActivityManagerService也是在SystemServer启动的时候创建的,

[java] view
plaincopy





class ServerThread {

.......

public void initAndLoop() {

......

context = ActivityManagerService.main(factoryTest); //启动AMS

.......

ActivityManagerService.setSystemProcess(); //向Service Manager注册

.......

}

}

需要在一个新线程中初始化ActivityManagerService,ActivityManagerService用了单例模式。

[java] view
plaincopy





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;

}

二、ActivityStackSupervisor和ActivityStack管理Activity的状态

1.ActivityState

描述一个Activity可能经历的所有状态,定义在ActivityStack.java文件中:

[java] view
plaincopy





enum ActivityState {

INITIALIZING, //正在初始化

RESUMED, //已经恢复

PAUSING, //正在暂停

PAUSED, //已经暂停

STOPPING, //正在停止

STOPPED, //已经停止

FINISHING, //正在完成

DESTROYING, //正在销毁

DESTROYED //已经销毁

}

状态变换图:



[java] view
plaincopy





/**

* 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

[java] view
plaincopy





/** 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命令查看而得知:

[java] view
plaincopy





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时,

[java] view
plaincopy





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

[java] view
plaincopy





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);

}

[java] view
plaincopy





void setWindowManager(WindowManagerService wm) { //ActivityStackSupervisor.java中

mWindowManager = wm;

mHomeStack = new ActivityStack(mService, mContext, mLooper, HOME_STACK_ID);

mStacks.add(mHomeStack); //放在了第0个位置

}

mFocusedStack存放的是应用程序的task,所以它的创建是在Activity启动的时候,Activity的启动过程可以参考Android4.4 framework分析——Launcher中启动应用程序(startActivity)的过程step16,startActivityUncheckedLocked()中,

[java] view
plaincopy





if (r.resultTo == null && !addingToTask

&& (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {

targetStack = adjustStackFocus(r); //targetStack即目标Stack,r要加入的stack

[java] view
plaincopy





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,

[java] view
plaincopy





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);

}

}

}</span>

[java] view
plaincopy





<span style="font-size:18px;"> 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里什么情况下会出现第三或第四个元素,这个不知道,目前没有发现这种情况。。。

未完待续,有不对的地方,请指正。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: