Andorid 4.4 AMS(一 数据结构)

最近看4,4的源码,跟网上讲的ams变的太多了,那个什么mMainStack,还有什么mHistoryRecord等根本找不到,看的一头雾水,先总结下基本的数据结构吧。

其实说白了,他所谓的stack全部都是ArrayList,用ArrayList来模拟stack,开始还很纳闷既然是stack怎么去里边找activity,不是操作栈顶元素么?

全局一个总的stack:

 /** All the non-launcher stacks */
    private ArrayList<ActivityStack> mStacks = new ArrayList<ActivityStack>();

这个mStacks存储了所有的stack,其中每一个stack中存储是一个个的task,每一个task中存储的是一堆activity。

总体的大小关系是:

mStacks>Stack>task【开始没搞清楚大小关系,纠结了半天,从这个代码就可以看出】

  void removeTask(TaskRecord task) {
        mWindowManager.removeTask(task.taskId);
        final ActivityStack stack = task.stack;
        final ActivityRecord r = stack.mResumedActivity;
        if (r != null && r.task == task) {
            stack.mResumedActivity = null;
        }
        if (stack.removeTask(task) && !stack.isHomeStack()) {
            if (DEBUG_STACK) Slog.i(TAG, "removeTask: removing stack " + stack);
            mStacks.remove(stack);
            final int stackId = stack.mStackId;
            final int nextStackId = mWindowManager.removeStack(stackId);
            // TODO: Perhaps we need to let the ActivityManager determine the next focus...
            if (mFocusedStack == null || mFocusedStack.mStackId == stackId) {
                // If this is the last app stack, set mFocusedStack to null.
                mFocusedStack = nextStackId == HOME_STACK_ID ? null : getStack(nextStackId);
            }
        }
    }

这里删除是个task,首先拿到这个task所在的stack,就是第3行代码,然后删除掉这个stack中的task,然后注意这行代码:

  mStacks.remove(stack);

为毛我只删除个task,你就要把我的stack也删掉?难不成task>stack??

关键点在这:

if (stack.removeTask(task) && !stack.isHomeStack()) {

这个if语句,我们回到stack中去看看他的removeTask的实现:

  boolean removeTask(TaskRecord task) {
        final int taskNdx = mTaskHistory.indexOf(task);
        final int topTaskNdx = mTaskHistory.size() - 1;
        if (task.mOnTopOfHome && taskNdx < topTaskNdx) {
            mTaskHistory.get(taskNdx + 1).mOnTopOfHome = true;
        }
        mTaskHistory.remove(task);
        return mTaskHistory.isEmpty();
    }

原来在stack中删除task的时候,最后会做出个判断,看当前stack中的task是否为空,如果为没东西了,那么这个stack也就可以删除了。

这也就证明了mStacks>stack>task

遍观整个ActivityStackSupervisor.java会发现其实关于stack除了mStacks是整个stack的集合,一共也就2个stack,分别是:

  /** 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;

就这2个东西,
mHomeStack存储luncher相关的内容,也就是home,另一个存储当前处于焦点的stack,mHomeStack会在开机之后自动加入到mStacks中去,而且只占据第0号位置,mFocusedStack占据第1号位置,

    void setWindowManager(WindowManagerService wm) {
        mWindowManager = wm;
        mHomeStack = new ActivityStack(mService, mContext, mLooper, HOME_STACK_ID);//初始化home
        mStacks.add(mHomeStack);
    }

调试的时候开启了10多个应用,发现这些应用的activity全部放到了mFocusedStack中,mStacks中第2个位置始终没有被使用很纳闷,不知道是不是我应用开的不够多,如果仅仅用2个位置的话,那么要mStacks岂不是多此一举?这个还得好好琢磨琢磨。

看这个:

   ActivityStack getLastStack() {
        switch (mStackState) {
            case STACK_STATE_HOME_IN_FRONT:
            case STACK_STATE_HOME_TO_BACK:
                return mHomeStack;
            case STACK_STATE_HOME_TO_FRONT:
            case STACK_STATE_HOME_IN_BACK:
            default:
                return mFocusedStack;
        }
    }

貌似就是在这两个stack中来回切换,关于是否会使用第3个位置,还有需要进一步确认。

    原文作者:xueerfei
    原文地址: https://blog.csdn.net/xueerfei008/article/details/23171677
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞