Android4.4 framework分析——ActivityManagerService的启动和对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里什么情况下会出现第三或第四个元素,这个不知道,目前没有发现这种情况。。。

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

时间: 2024-08-11 10:46:25

Android4.4 framework分析——ActivityManagerService的启动和对Activity的管理的相关文章

Android4.4 Framework分析——Android默认Home应用Launcher3的加载过程分析

本文主要介绍Android4.4默认Home应用Launcher3的启动过程和Launcher3的数据加载过程.Launcher的启动是开机时,ActivityManagerService准备好后开始的,下图是它的启动序列图: step1,SystemServer中,ActivityManagerService准备好了. step3, boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord targe

Android4.4 Framework分析——Activity窗口的创建过程(一)

学习android的窗口模块一周多了,感觉自己对这个模块的理解还是比较模糊,先把get的知识点记录一下. 下图是学习过程记录的activity窗口启动过程序列图,没有或者没办法完整的描绘出来,整个过程比较复杂: 整个学习过程中是参照老罗的android之旅博客和<深入理解android内核设计思想>一书来辅助的,非常感谢前辈. Activity的整体启动过程可查看Android4.4 framework分析--Launcher中启动应用程序(startActivity)的过程的序列图,本文关注

Android4.4 framework分析——Zygote进程的启动过程

Android启动过程中的第一个进程init,在启动过程中会启动两个关键的系统服务进程ServiceManager和Zygote.本文要介绍的就是Zygote进程的启动,Zygote俗称孵化器,专门用于生产(启动)新的进程.Zygote是在Init.rc(aosp/system/core/rootdir)里描述并由init进程启动的.相关代码如下: service zygote /system/bin/app_process -Xzygote /system/bin --zygote --sta

Android4.4 Framework分析——startService创建过程

我们经常使用context.startService()要启动service.下面就来分析这service启动过程,下图是service启动序列图: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY2FuZ2hhaTExMjk=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" > step2.mBase.startService()中mBase定义为

Android4.4 framework分析——getContentResolver启动ContentProvider的过程

ContentProvider的创建一般是在第一次使用的时候. 没时间分析,可参考老罗的分析 http://blog.csdn.net/luoshengyang/article/details/6963418

Android4.4 framework分析——startService的创建过程

我们常用context.startService()来启动一个service,下面来分析一下这个service的启动过程,下图是service启动的序列图: step2,mBase.startService()中mBase定义为Context,它的真实实现是ContextImpl对象(看名字就知道是Context的实现类). step4,ActivityManagerNative.getDefault().startService()中ActivityManagerNative.getDefau

Android4.4 framework分析——广播的注册(BroadcastReceiver)和发送(sendbroadcast)过程分析

在Android应用程序框架中,Activity和Service类都继承了ContextWrapper类,因此,我们可以在Activity或者Service的子类中调用registerReceiver函数来注册广播接收器. 下图是在activity中注册广播的过程: step1~step3,就是一般的调用过程. step4,registerReceiverInternal()方法如下: private Intent registerReceiverInternal(BroadcastReceiv

Android4.0(Phone)拨号启动过程分析(三)与Framework层通信

由于Android几乎所有的代码都是公开的,如果要对Framework层分析就必需先拿到Framework层的代码,我在前面已经搭建好了ubuntu14.04的环境,下载好了Android4.0的源码,其中也包括了Framework层和Package的代码,导出到宿主机Windows XP中用Source Insight 3.5工具来查看源码,Package中的代码可以导入到Eclipse下查看,我是把frameworks\base整个目录都导入到Source Insight 3.5工程中,可以

Android4.0(Phone)拨号启动过程分析(二)

接上:Android4.0(Phone)拨号启动过程分析(一) InCallScreen处理来电和拨号的界面,接通电话也是这个界面,接下来分析InCallScreen类是如何处理拨号流程的: @Override protected void onCreate(Bundle icicle) { Log.i(LOG_TAG, "onCreate()... this = " + this); Profiler.callScreenOnCreate(); super.onCreate(icic