Android6.0 AMS启动Activity(四) AMS内部一些成员变量

来源:互联网 发布:淘宝三个月前订单不见 编辑:程序博客网 时间:2024/05/18 00:35

之前在分析AMS和ActivityStackSupervisor和ActivityStack对一些成员变量比较模糊,这篇博客主要讲下这些成员变量


一、AMS成员变量的初始化

我们先来看看AMS在systemServer的构造,初始化,先是调用了在SystemServiceManager中调用了AMS的构造函数。

        mActivityManagerService = mSystemServiceManager.startService(                ActivityManagerService.Lifecycle.class).getService();        mActivityManagerService.setSystemServiceManager(mSystemServiceManager);        mActivityManagerService.setInstaller(installer);

构造函数主要是初始化了一些成员变量,下面我们来看如下两个成员变量,mRecenTasks代表最近的几个task

        mRecentTasks = new RecentTasks(this);        mStackSupervisor = new ActivityStackSupervisor(this, mRecentTasks);

在ActivityStackSupervisor的构造函数就是创建了一个handler,然后把service和recentTasks保存在成员变量中。

    public ActivityStackSupervisor(ActivityManagerService service, RecentTasks recentTasks) {        mService = service;        mRecentTasks = recentTasks;        mHandler = new ActivityStackSupervisorHandler(mService.mHandler.getLooper());    }

随后在SystemServer中会调用如下代码,就是把SystemServer这个进程保存进程信息。

mActivityManagerService.setSystemProcess();

再后面我们看下如下代码,把WMS对象设置到AMS中去。

mActivityManagerService.setWindowManager(wm);
看下AMS的setWindowManager函数,保存了WMS,然后调用了ActivityStackSupervisor的setWindowManager函数。
    public void setWindowManager(WindowManagerService wm) {        mWindowManager = wm;        mStackSupervisor.setWindowManager(wm);    }
看下ActivityStackSupervisor的setWindowManager函数,在这个函数中先获取所有的显示设备,然后一一对应创建ActivityDisplay对象,接着调用createStackOnDisplay对象创建获取displayId的ActivityContainer,在ActivityContainer中又创建了ActivitStack对象。
    void setWindowManager(WindowManagerService wm) {        synchronized (mService) {            mWindowManager = wm;            mDisplayManager =                    (DisplayManager)mService.mContext.getSystemService(Context.DISPLAY_SERVICE);            mDisplayManager.registerDisplayListener(this, null);            Display[] displays = mDisplayManager.getDisplays();//获取所有的显示设备            for (int displayNdx = displays.length - 1; displayNdx >= 0; --displayNdx) {                final int displayId = displays[displayNdx].getDisplayId();                ActivityDisplay activityDisplay = new ActivityDisplay(displayId);//每一个显示设备创建一个对象的ActivityDisplay                if (activityDisplay.mDisplay == null) {                    throw new IllegalStateException("Default Display does not exist");                }                mActivityDisplays.put(displayId, activityDisplay);            }            createStackOnDisplay(HOME_STACK_ID, Display.DEFAULT_DISPLAY);//创建ActivityStack            mHomeStack = mFocusedStack = mLastFocusedStack = getStack(HOME_STACK_ID);            mInputManagerInternal = LocalServices.getService(InputManagerInternal.class);            // Initialize this here, now that we can get a valid reference to PackageManager.            mLeanbackOnlyDevice = isLeanbackOnlyDevice();        }    }
在createStackOnDisplay函数,会获取传入的displayId获取activityDisplay ,然后创建一个ActivityContainer在这个对象的构造函数中会创建一个ActivityStack对象,最后调用attachToDisplayLocked把这个activityDisplay和activityContainer 联系起来。

    ActivityStack createStackOnDisplay(int stackId, int displayId) {        ActivityDisplay activityDisplay = mActivityDisplays.get(displayId);        if (activityDisplay == null) {            return null;        }        ActivityContainer activityContainer = new ActivityContainer(stackId);        mActivityContainers.put(stackId, activityContainer);//把activityContainer放入mActivityContainers中        activityContainer.attachToDisplayLocked(activityDisplay);        return activityContainer.mStack;    }

我们再来看下ActivityContainer 的attachToDisplayLocked函数,ActivityStack的mStacks是每一个显示设备上所有的ActivityStack。

        void attachToDisplayLocked(ActivityDisplay activityDisplay) {            if (DEBUG_STACK) Slog.d(TAG_STACK, "attachToDisplayLocked: " + this                    + " to display=" + activityDisplay);            mActivityDisplay = activityDisplay;            mStack.mDisplayId = activityDisplay.mDisplayId;            mStack.mStacks = activityDisplay.mStacks;            activityDisplay.attachActivities(mStack);            mWindowManager.attachStack(mStackId, activityDisplay.mDisplayId);        }
我们再来看ActivityDisplay的attachActivities函数,把当前的ActivityStack放在ActivityDisplay的mStacks中。

        void attachActivities(ActivityStack stack) {            if (DEBUG_STACK) Slog.v(TAG_STACK,                    "attachActivities: attaching " + stack + " to displayId=" + mDisplayId);            mStacks.add(stack);        }

所以每一个ActivityStack的mStacks变量代表的是这个显示设备上所有的ActivityStack。


然后我们再来看下面这句,调用getStack,传入的stackId就是HOME_STACK_ID,这样刚才创建的ActivityStack就赋给这些成员变量。这里mHomeStack就不会改变了,然后mFocusedStack和mLastFocusedStack会改变的。

mHomeStack = mFocusedStack = mLastFocusedStack = getStack(HOME_STACK_ID);


二、startActivity流程

之前分析startActivity的时候,最后在ActivityStackSupervisor的startActivityUncheckedLocked函数分为两种情况,一种就是需要新建TaskRecord,另一种不需要新建TaskRecord。

2.1 需要创建新TaskRecord

现在我们再来看startActivity流程,回顾下在ActivityStackSupervisor的startActivityUncheckedLocked函数中,当需要创建一个新的task的时候,到如下代码线调用computeStackFocus函数创建了一个ActivityStack,然后调用ActivityStack的moveToFront函数

        if (r.resultTo == null && inTask == null && !addingToTask                && (launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {            newTask = true;            targetStack = computeStackFocus(r, newTask);//创建ActivityStack            targetStack.moveToFront("startingNewTask");//将当前的ActivityStack放在最前面            if (reuseTask == null) {                r.setTask(targetStack.createTaskRecord(getNextTaskId(),                        newTaskInfo != null ? newTaskInfo : r.info,                        newTaskIntent != null ? newTaskIntent : intent,                        voiceSession, voiceInteractor, !launchTaskBehind /* toTop */),                        taskToAffiliate);                if (DEBUG_TASKS) Slog.v(TAG_TASKS,                        "Starting new activity " + r + " in new task " + r.task);            } else {                r.setTask(reuseTask, taskToAffiliate);            }            if (isLockTaskModeViolation(r.task)) {                Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r);                return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;            }            if (!movedHome) {                if ((launchFlags &                        (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME))                        == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) {                    // Caller wants to appear on home activity, so before starting                    // their own activity we will bring home to the front.                    r.task.setTaskToReturnTo(HOME_ACTIVITY_TYPE);                }            }        }

我们先来看computeStackFocus函数,先是获取ActivityRecord的task对象,这个时候我们需要建一个task,所以显然为null。这个函数就是寻找合适的ActivityStack,最后没找到就调用createStackOnDisplay函数创建一个ActivityContainer对象,当然也就创建了ActivityStack对象了。

    ActivityStack computeStackFocus(ActivityRecord r, boolean newTask) {        final TaskRecord task = r.task;//为null        // On leanback only devices we should keep all activities in the same stack.        if (!mLeanbackOnlyDevice &&                (r.isApplicationActivity() || (task != null && task.isApplicationTask()))) {            ActivityStack stack;            if (task != null && task.stack != null) {//如果当前TaskRecord中有stack,这里显然没有                stack = task.stack;                if (stack.isOnHomeDisplay()) {                    if (mFocusedStack != stack) {                        if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,                                "computeStackFocus: Setting " + "focused stack to r=" + r                                + " task=" + task);                    } else {                        if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,                            "computeStackFocus: Focused stack already=" + mFocusedStack);                    }                }                return stack;            }            final ActivityContainer container = r.mInitialActivityContainer;            if (container != null) {                // The first time put it on the desired stack, after this put on task stack.                r.mInitialActivityContainer = null;                return container.mStack;            }            if (mFocusedStack != mHomeStack && (!newTask ||//mFousedStack不是HomeStack,而且不是新建Task                    mFocusedStack.mActivityContainer.isEligibleForNewTasks())) {                if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,                        "computeStackFocus: Have a focused stack=" + mFocusedStack);                return mFocusedStack;            }            final ArrayList<ActivityStack> homeDisplayStacks = mHomeStack.mStacks;//所有设备上的ActivityStack            for (int stackNdx = homeDisplayStacks.size() - 1; stackNdx >= 0; --stackNdx) {                stack = homeDisplayStacks.get(stackNdx);                if (!stack.isHomeStack()) {//如果StackId不是HOME_STACK_ID                    if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,                            "computeStackFocus: Setting focused stack=" + stack);                    return stack;                }            }            // Need to create an app stack for this user.            stack = createStackOnDisplay(getNextStackId(), Display.DEFAULT_DISPLAY);//最后还是没找到创建一个ActivityContainer对象            if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS, "computeStackFocus: New stack r="                    + r + " stackId=" + stack.mStackId);            return stack;        }        return mHomeStack;    }

然后我们再来看下ActivityStack的moveToFront函数,先看看当前是否是HOME_STACK_ID的Stack,如果不是将当前的stack放在mStacks的最前面。mStacks之前看过代表这个显示设备上所有的Stack.

    final void moveToFront(String reason) {        if (isAttached()) {            final boolean homeStack = isHomeStack()//看是否是HOME_STACK_ID的Stack                    || (mActivityContainer.mParentActivity != null                        && mActivityContainer.mParentActivity.isHomeActivity());            ActivityStack lastFocusStack = null;            if (!homeStack) {                // Need to move this stack to the front before calling                // {@link ActivityStackSupervisor#moveHomeStack} below.                lastFocusStack = mStacks.get(mStacks.size() - 1);//获取最后的Stack                mStacks.remove(this);//去除当前stack                mStacks.add(this);//再加入,这样当前的stack就在最前面了            }            // TODO(multi-display): Focus stack currently adjusted in call to move home stack.            // Needs to also work if focus is moving to the non-home display.            if (isOnHomeDisplay()) {//是否是默认显示设备                mStackSupervisor.moveHomeStack(homeStack, reason, lastFocusStack);            }            final TaskRecord task = topTask();            if (task != null) {                mWindowManager.moveTaskToTop(task.taskId);//通知wms            }        }    }

我们再来看看ActivityStackSuperVisor的moveHomeStack函数,这里就是主要是赋值mLastFocusedStack 和 mFocusedStack 。mFocusedStack 就是上面函数刚刚放到mStacks中去的那个ActivityStack,mLastFocusedStack 就是上一个mStacks的最前面的ActivityStack。

    void moveHomeStack(boolean toFront, String reason, ActivityStack lastFocusedStack) {        ArrayList<ActivityStack> stacks = mHomeStack.mStacks;        final int topNdx = stacks.size() - 1;        if (topNdx <= 0) {            return;        }        // The home stack should either be at the top or bottom of the stack list.        if ((toFront && (stacks.get(topNdx) != mHomeStack))                || (!toFront && (stacks.get(0) != mHomeStack))) {            if (DEBUG_STACK) Slog.d(TAG_STACK, "moveHomeTask: topStack old="                    + ((lastFocusedStack != null) ? lastFocusedStack : stacks.get(topNdx))                    + " new=" + mFocusedStack);            stacks.remove(mHomeStack);            stacks.add(toFront ? topNdx : 0, mHomeStack);        }        if (lastFocusedStack != null) {            mLastFocusedStack = lastFocusedStack;        }        mFocusedStack = stacks.get(topNdx);

再来继续看ActivityStackSupervisor的startActivityUncheckedLocked函数,接下来就是来创建TaskRecord。然后调用ActivityRecord的setTask,把这个创建了TaskRecord作为ActivityRecord的task对象。
            if (reuseTask == null) {                r.setTask(targetStack.createTaskRecord(getNextTaskId(),                        newTaskInfo != null ? newTaskInfo : r.info,                        newTaskIntent != null ? newTaskIntent : intent,                        voiceSession, voiceInteractor, !launchTaskBehind /* toTop */),                        taskToAffiliate);                if (DEBUG_TASKS) Slog.v(TAG_TASKS,                        "Starting new activity " + r + " in new task " + r.task);            }
我们看ActivityStack的createTaskRecord函数,创建一个TaskRecord。然后调用addTask把TaskRecord保存下来。
    TaskRecord createTaskRecord(int taskId, ActivityInfo info, Intent intent,            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,            boolean toTop) {        TaskRecord task = new TaskRecord(mService, taskId, info, intent, voiceSession,                voiceInteractor);        addTask(task, toTop, false);        return task;    }
addTask先把当前的ActivityStack放在这TaskRecord的stack成员变量中,然后就是把这个TaskRecord放在mTaskHistory一个合适的位置。
    void addTask(final TaskRecord task, final boolean toTop, boolean moving) {        task.stack = this;//把当前ActivityStack放在这TaskRecord的stack成员变量中        if (toTop) {            insertTaskAtTop(task, null);        } else {            mTaskHistory.add(0, task);            updateTaskMovement(task, false);        }        if (!moving && task.voiceSession != null) {            try {                task.voiceSession.taskStarted(task.intent, task.taskId);            } catch (RemoteException e) {            }        }    }

2.2 不需要新建TaskReocrd

我们还是看下ActivityStackSupervisor的startActivityUncheckedLocked函数,下面是不要创建新的TaskReocrd的流程。先直接从ActivityRecord的task获取TaskRecord对象。

然后从TaskRecord的stack获取ActivityStack对象。和上面流程一样,先调用ActivityStack的moveToFront将当前这个ActivityStack放在最前面,同时改变mFocusedStack和mLastFocusedStack的值。然后又看当前这个TaskRecord是否是当前ActivityStack最前面的。如果不是把它调整到最前面

        } else if (sourceRecord != null) {            final TaskRecord sourceTask = sourceRecord.task;            if (isLockTaskModeViolation(sourceTask)) {                Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r);                return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;            }            targetStack = sourceTask.stack;            targetStack.moveToFront("sourceStackToFront");//把当前ActivityStack放在最前面            final TaskRecord topTask = targetStack.topTask();            if (topTask != sourceTask) {                targetStack.moveTaskToFrontLocked(sourceTask, noAnimation, options,//把当前TaskRecord放在ActivityStack的最前面                        r.appTimeTracker, "sourceTaskToFront");            }


三、将Activity放在TaskRecord的最前面

下面我们再来看ActivityStack的startActivityLocked函数有下面代码,会把当前要启动的Activity放在TaskRecord的最前面

        task = r.task;        // Slot the activity into the history stack and proceed        if (DEBUG_ADD_REMOVE) Slog.i(TAG, "Adding activity " + r + " to stack to task " + task,                new RuntimeException("here").fillInStackTrace());        task.addActivityToTop(r);        task.setFrontOfTask();


四、保存TaskRecord到mRecentTasks

我们继续分析ActivityStatck的resumeTopActivityInnerLocked函数,先分析要启动的Activity已经有进程了,这里我会先调用mRecentTasks.addLocked把现在的TaskRecord保存在mRecentTasks代表最近启动的Task

        if (next.app != null && next.app.thread != null) {            if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Resume running: " + next);            // This activity is now becoming visible.            mWindowManager.setAppVisibility(next.appToken, true);            // schedule launch ticks to collect information about slow apps.            next.startLaunchTickingLocked();            ActivityRecord lastResumedActivity =                    lastStack == null ? null :lastStack.mResumedActivity;            ActivityState lastState = next.state;            mService.updateCpuStats();            if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to RESUMED: " + next + " (in existing)");            next.state = ActivityState.RESUMED;            mResumedActivity = next;            next.task.touchActiveTime();            mRecentTasks.addLocked(next.task);//保存TaskRecord在mRecentTasks            mService.updateLruProcessLocked(next.app, true, null);            updateLRUListLocked(next);            mService.updateOomAdjLocked();            ......            try {                // Deliver all pending results.                ArrayList<ResultInfo> a = next.results;                if (a != null) {                    final int N = a.size();                    if (!next.finishing && N > 0) {                        if (DEBUG_RESULTS) Slog.v(TAG_RESULTS,                                "Delivering results to " + next + ": " + a);                        next.app.thread.scheduleSendResult(next.appToken, a);                    }                }                ......                next.app.thread.scheduleResumeActivity(next.appToken, next.app.repProcState,//调用ActivityThread的函数                        mService.isNextTransitionForward(), resumeAnimOptions);

那如果启动没有进程的Activity又是在哪保存TaskRecord到mRecentTasks的呢。如果没有进程会调用startSpecificActivityLocked函数,最后又到ActivityThread的main函数,又调用AMS的attachApplicationLocked函数。在AMS的attachApplicationLocked函数中又会调用ActivityStackSupervisor的attachApplicationLocked方法。

    void startSpecificActivityLocked(ActivityRecord r,            boolean andResume, boolean checkConfig) {        // Is this activity's application already running?        ProcessRecord app = mService.getProcessRecordLocked(r.processName,                r.info.applicationInfo.uid, true);        r.task.stack.setLaunchTime(r);        if (app != null && app.thread != null) {            try {                if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0                        || !"android".equals(r.info.packageName)) {                    // Don't add this if it is a platform component that is marked                    // to run in multiple processes, because this is actually                    // part of the framework so doesn't make sense to track as a                    // separate apk in the process.                    app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode,                            mService.mProcessStats);                }                realStartActivityLocked(r, app, andResume, checkConfig);                return;            } catch (RemoteException e) {                Slog.w(TAG, "Exception when starting activity "                        + r.intent.getComponent().flattenToShortString(), e);            }            // If a dead object exception was thrown -- fall through to            // restart the application.        }        mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,                "activity", r.intent.getComponent(), false, false, true);    }

在ActivityStackSupervisor的attachApplicationLocked方法中又调用了realStartActivityLocked方法,在realStartActivityLocked方法中会调用app.thread.scheduleLaunchActivity启动Activity,后面还会调用ActivityStac的minimalResumeActivityLocked方法。

在这个函数中调用了mRecentTasks.addLocked方法保存了TaskRecord,还保存了mResumedActivity。

    void minimalResumeActivityLocked(ActivityRecord r) {        r.state = ActivityState.RESUMED;        if (DEBUG_STATES) Slog.v(TAG_STATES,                "Moving to RESUMED: " + r + " (starting new instance)");        r.stopped = false;        mResumedActivity = r;        r.task.touchActiveTime();        mRecentTasks.addLocked(r.task);        completeResumeLocked(r);        mStackSupervisor.checkReadyForSleepLocked();        setLaunchTime(r);        if (DEBUG_SAVED_STATE) Slog.i(TAG_SAVED_STATE,                "Launch completed; removing icicle of " + r.icicle);    }




1 0
原创粉丝点击