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

原文地址:http://blog.csdn.net/canghai1129/article/details/41392247

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

一、ActivityManagerService的启动

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

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. class ServerThread {  
  2.     .......  
  3.    public void initAndLoop() {  
  4.     ......  
  5.     context = ActivityManagerService.main(factoryTest); //启动AMS  
  6.     .......  
  7.     ActivityManagerService.setSystemProcess(); //向Service Manager注册  
  8.     .......  
  9.    }  
  10.  }  
需要在一个新线程中初始化ActivityManagerService,ActivityManagerService用了单例模式。
[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. public static final Context main(int factoryTest) {  
  2.        AThread thr = new AThread();  
  3.        thr.start(); //启动一个线程来启动  
  4.   
  5.        synchronized (thr) {  
  6.            while (thr.mService == null) {  
  7.                try {  
  8.                    thr.wait();//线程等待activitymanagerservice初始化完成  
  9.                } catch (InterruptedException e) {  
  10.                }  
  11.            }  
  12.        }  
  13.   
  14.        ActivityManagerService m = thr.mService;  
  15.        mSelf = m;  
  16.        ActivityThread at = ActivityThread.systemMain(); //启动一个主线程  
  17.        mSystemThread = at;  
  18.        Context context = at.getSystemContext();  
  19.        context.setTheme(android.R.style.Theme_Holo);  
  20.         ......  
  21.        m.mStackSupervisor = new ActivityStackSupervisor(m, context, thr.mLooper); //新建一个activity堆栈管理辅助类实例  
  22.   
  23.        .......  
  24.        synchronized (thr) {  
  25.            thr.mReady = true;  
  26.            thr.notifyAll(); //activitymanagerservice启动完成  
  27.        }  
  28.   
  29.        m.startRunning(nullnullnullnull);  
  30.   
  31.        return context;  
  32.    }  

二、ActivityStackSupervisor和ActivityStack管理Activity的状态

1.ActivityState

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

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. enum ActivityState {  
  2.     INITIALIZING, //正在初始化  
  3.     RESUMED, //已经恢复  
  4.     PAUSING, //正在暂停  
  5.     PAUSED, //已经暂停  
  6.     STOPPING, //正在停止  
  7.     STOPPED, //已经停止  
  8.     FINISHING, //正在完成  
  9.     DESTROYING, //正在销毁  
  10.     DESTROYED //已经销毁  
  11. }  
  状态变换图:


[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. /** 
  2.  * The back history of all previous (and possibly still 
  3.  * running) activities.  It contains #TaskRecord objects. 
  4.  */  
  5. private ArrayList<TaskRecord> mTaskHistory = new ArrayList<TaskRecord>();  
  6.   
  7. /** 
  8.  * Used for validating app tokens with window manager. 
  9.  */  
  10. final ArrayList<TaskGroup> mValidateAppTokens = new ArrayList<TaskGroup>();  
  11.   
  12. /** 
  13.  * List of running activities, sorted by recent usage. 
  14.  * The first entry in the list is the least recently used. 
  15.  * It contains HistoryRecord objects. 
  16.  */  
  17. final ArrayList<ActivityRecord> mLRUActivities = new ArrayList<ActivityRecord>();  
  18.   
  19. /** 
  20.  * Animations that for the current transition have requested not to 
  21.  * be considered for the transition animation. 
  22.  */  
  23. final ArrayList<ActivityRecord> mNoAnimActivities = new ArrayList<ActivityRecord>();  
  24.   
  25. /** 
  26.  * When we are in the process of pausing an activity, before starting the 
  27.  * next one, this variable holds the activity that is currently being paused. 
  28.  */  
  29. ActivityRecord mPausingActivity = null;  
  30.   
  31. /** 
  32.  * This is the last activity that we put into the paused state.  This is 
  33.  * used to determine if we need to do an activity transition while sleeping, 
  34.  * when we normally hold the top activity paused. 
  35.  */  
  36. ActivityRecord mLastPausedActivity = null;  
  37.   
  38. /** 
  39.  * Activities that specify No History must be removed once the user navigates away from them. 
  40.  * If the device goes to sleep with such an activity in the paused state then we save it here 
  41.  * and finish it later if another activity replaces it on wakeup. 
  42.  */  
  43. ActivityRecord mLastNoHistoryActivity = null;  
  44.   
  45. /** 
  46.  * Current activity that is resumed, or null if there is none. 
  47.  */  
  48. ActivityRecord mResumedActivity = null;  
  49.   
  50. /** 
  51.  * This is the last activity that has been started.  It is only used to 
  52.  * identify when multiple activities are started at once so that the user 
  53.  * can be warned they may not be in the activity they think they are. 
  54.  */  
  55. ActivityRecord mLastStartedActivity = null;  
ActivityRecord变量的具体含义,可查看注释。


2.记录Activity的ArrayList和ActivityStack

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. /** The stack containing the launcher app */  
  2. private ActivityStack mHomeStack;  
  3.   
  4. /** The non-home stack currently receiving input or launching the next activity. If home is 
  5.  * in front then mHomeStack overrides mFocusedStack. 
  6.  * DO NOT ACCESS DIRECTLY - It may be null, use getFocusedStack() */  
  7. private ActivityStack mFocusedStack;  
  8.   
  9. /** All the non-launcher stacks */  
  10. 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 plain copy 在CODE上查看代码片 派生到我的代码片
  1. ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)   
  2.   Stack #0:   
  3.     Task id #1   
  4.       TaskRecord{b22161f0 #1 A=com.android.launcher U=0 sz=1}   
  5.       Intent { act=android.intent.action.MAIN cat=[android.intent.category.HOME] flg=0x10200000 cmp=com.android.launcher/com.android.launcher2.Launcher }   
  6.         Hist #0: ActivityRecord{b2214570 u0 com.android.launcher/com.android.launcher2.Launcher t1}   
  7.           Intent { act=android.intent.action.MAIN cat=[android.intent.category.HOME] flg=0x10000000 cmp=com.android.launcher/com.android.launcher2.Launcher }   
  8.           ProcessRecord{b21df5c8 1402:com.android.launcher/u0a8}   
  9.     Task id #3   
  10.       TaskRecord{b2288fd0 #3 A=com.android.systemui U=0 sz=1}   
  11.       Intent { act=com.android.systemui.recent.action.TOGGLE_RECENTS flg=0x10800000 cmp=com.android.systemui/.recent.RecentsActivity bnds=[132,331][296,476] (has extras) }   
  12.         Hist #0: ActivityRecord{b22d5aa0 u0 com.android.systemui/.recent.RecentsActivity t3}   
  13.           Intent { act=com.android.systemui.recent.action.TOGGLE_RECENTS flg=0x10800000 cmp=com.android.systemui/.recent.RecentsActivity bnds=[132,331][296,476] (has extras) }   
  14.           ProcessRecord{b2169ac8 1313:com.android.systemui/u0a7}   
  15.    
  16.     Running activities (most recent first):   
  17.       TaskRecord{b22161f0 #1 A=com.android.launcher U=0 sz=1}   
  18.         Run #1: ActivityRecord{b2214570 u0 com.android.launcher/com.android.launcher2.Launcher t1}   
  19.       TaskRecord{b2288fd0 #3 A=com.android.systemui U=0 sz=1}   
  20.         Run #0: ActivityRecord{b22d5aa0 u0 com.android.systemui/.recent.RecentsActivity t3}   
  21.    
  22.   Stack #1:   
  23.     Task id #4   
  24.       TaskRecord{b21e57d0 #4 A=android.task.contacts U=0 sz=1}   
  25.       Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.android.contacts/.activities.PeopleActivity }   
  26.         Hist #0: ActivityRecord{b2281e68 u0 com.android.contacts/.activities.PeopleActivity t4}   
  27.           Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.android.contacts/.activities.PeopleActivity bnds=[64,417][128,481] }   
  28.           ProcessRecord{b22f66c0 1820:com.android.contacts/u0a2}   
  29.    
  30.     Task id #2   
  31.       TaskRecord{b2229370 #2 A=com.android.dialer U=0 sz=1}   
  32.       Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.android.dialer/.DialtactsActivity }   
  33.         Hist #0: ActivityRecord{b223d3c8 u0 com.android.dialer/.DialtactsActivity t2}   
  34.           Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.android.dialer/.DialtactsActivity bnds=[0,417][64,481] }   
  35.           ProcessRecord{b2215d48 1569:com.android.dialer/u0a4}   
  36.    
  37.     Running activities (most recent first):   
  38.       TaskRecord{b21e57d0 #4 A=android.task.contacts U=0 sz=1}   
  39.         Run #1: ActivityRecord{b2281e68 u0 com.android.contacts/.activities.PeopleActivity t4}   
  40.       TaskRecord{b2229370 #2 A=com.android.dialer U=0 sz=1}   
  41.         Run #0: ActivityRecord{b223d3c8 u0 com.android.dialer/.DialtactsActivity t2}   
  42.    
  43.     mResumedActivity: ActivityRecord{b2281e68 u0 com.android.contacts/.activities.PeopleActivity t4}   
  44.    
  45.   mFocusedActivity: ActivityRecord{b2281e68 u0 com.android.contacts/.activities.PeopleActivity t4}   
  46.   mDismissKeyguardOnNextActivity:false   
  47.   mStackState=STACK_STATE_HOME_IN_BACK   
  48.   mSleepTimeout: false   
  49.   mCurTaskId: 4   
  50.   mUserStackInFront: {}   
  51.    
  52.   Recent tasks:   
  53.   * Recent #0: TaskRecord{b21e57d0 #4 A=android.task.contacts U=0 sz=1}   
  54.   * Recent #1: TaskRecord{b22161f0 #1 A=com.android.launcher U=0 sz=1}   
  55.   * Recent #2: TaskRecord{b2229370 #2 A=com.android.dialer U=0 sz=1}   
  56.   * 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 plain copy 在CODE上查看代码片 派生到我的代码片
  1. ActivityManagerService.self().setWindowManager(wm); //SystemServer.java中  

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. 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>中  
  2.     mWindowManager = wm;  
  3.     mStackSupervisor.setWindowManager(wm);  
  4.     wm.createStack(HOME_STACK_ID, -1, StackBox.TASK_STACK_GOES_OVER, 1.0f);  
  5. }  

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. void setWindowManager(WindowManagerService wm) { //ActivityStackSupervisor.java中  
  2.     mWindowManager = wm;  
  3.     mHomeStack = new ActivityStack(mService, mContext, mLooper, HOME_STACK_ID);  
  4.     mStacks.add(mHomeStack); //放在了第0个位置  
  5. }  

 mFocusedStack存放的是应用程序的task,所以它的创建是在Activity启动的时候,Activity的启动过程可以参考Android4.4 framework分析——Launcher中启动应用程序(startActivity)的过程step16,startActivityUncheckedLocked()中,
[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. if (r.resultTo == null && !addingToTask  
  2.         && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {  
  3.     targetStack = adjustStackFocus(r); //targetStack即目标Stack,r要加入的stack  

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1.     ActivityStack adjustStackFocus(ActivityRecord r) {  
  2.         final TaskRecord task = r.task;  
  3.         //r是否是应用程序的activity类型,或者r所属task是应用程序task  
  4.         //android定义区分了三种不同的activity类型  
  5.         //static final int APPLICATION_ACTIVITY_TYPE = 0; //应用程序类型  
  6.         //static final int HOME_ACTIVITY_TYPE = 1; //Launcher类型  
  7.         //static final int RECENTS_ACTIVITY_TYPE = 2; //SystemUI的最近应用  
  8.         if (r.isApplicationActivity() || (task != null && task.isApplicationTask())) {   
  9.             if (task != null) {  
  10.                 if (mFocusedStack != task.stack) {  
  11.                     if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,  
  12.                             "adjustStackFocus: Setting focused stack to r=" + r + " task=" + task);  
  13.                     mFocusedStack = task.stack;  
  14.                 } else {  
  15.                     if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,  
  16.                         "adjustStackFocus: Focused stack already=" + mFocusedStack);  
  17.                 }  
  18.                 return mFocusedStack;//app类型的activity每次都加入mFocusedStack  
  19.             }  
  20.   
  21.             if (mFocusedStack != null) {  
  22.                 if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,  
  23.                         "adjustStackFocus: Have a focused stack=" + mFocusedStack);  
  24.                 return mFocusedStack;//app类型的activity每次都加入mFocusedStack  
  25.             }  
  26.   
  27.             for (int stackNdx = mStacks.size() - 1; stackNdx > 0; --stackNdx) {  
  28.                 ActivityStack stack = mStacks.get(stackNdx);  
  29.                 if (!stack.isHomeStack()) {  
  30.                     if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,  
  31.                             "adjustStackFocus: Setting focused stack=" + stack);  
  32.                     mFocusedStack = stack;  
  33.                     return mFocusedStack;//app类型的activity每次都加入mFocusedStack  
  34.                 }  
  35.             }  
  36.   
  37.             // Time to create the first app stack for this user.  
  38.             int stackId = mService.createStack(-1, HOME_STACK_ID, //启动第一个app,需要创建一个stack,其他app创建时,前面条件判断将拦截住  
  39.                 StackBox.TASK_STACK_GOES_OVER, 1.0f);  
  40.             if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, "adjustStackFocus: New stack r=" + r +  
  41.                     " stackId=" + stackId);  
  42.             mFocusedStack = getStack(stackId);  
  43.             return mFocusedStack; //app类型的activity每次都加入mFocusedStack  
  44.         }  
  45.         return mHomeStack;  
  46.     }  

从上面这个方法看出,Launcher类型和最近应用类型的task将加入mHomeStack中,而其他应用类型的task加入mFocusedStack,
[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. public int createStack(int taskId, int relativeStackBoxId, int position, float weight) {  
  2.     enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,  
  3.             "createStack()");  
  4.     synchronized (this) {  
  5.         long ident = Binder.clearCallingIdentity();  
  6.         try {  
  7.             int stackId = mStackSupervisor.createStack(); //看这里  
  8.             mWindowManager.createStack(stackId, relativeStackBoxId, position, weight);  
  9.             if (taskId > 0) {  
  10.                 moveTaskToStack(taskId, stackId, true);  
  11.             }  
  12.             return stackId;  
  13.         } finally {  
  14.             Binder.restoreCallingIdentity(ident);  
  15.         }  
  16.     }  
  17. }</span>  

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <span style="font-size:18px;">    int createStack() {   
  2.         while (true) {  
  3.             if (++mLastStackId <= HOME_STACK_ID) {  
  4.                 mLastStackId = HOME_STACK_ID + 1;  
  5.             }  
  6.             if (getStack(mLastStackId) == null) {  
  7.                 break;  
  8.             }  
  9.         }  
  10.         mStacks.add(new ActivityStack(mService, mContext, mLooper, mLastStackId)); //新建了一个Stack加入mStacks  
  11.         return mLastStackId;  
  12.     }  
createStack()方法只有一次机会执行,即第一次运行app。

mStacks里什么情况下会出现第三或第四个元素,这个不知道,目前没有发现这种情况。。。


未完待续,有不对的地方,请指正。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值