Android源码探究:Activity启动流程完全解析(上)

概述

本文主要内容是从源码角度进行Activity启动流程的分析。由于整个启动的过程非常长并且代码非常多,同时受限于笔者的水平,所以本文不会细致到解释每一行的代码的具体作用,只能抽取处关键部分的代码就主体流程进行分析,如有错误之处,希望批评指出。

行文脉络

由于本文会非常长,为了方便读者的理解,首先给出笔者的行文脉络。本文主要沿着:在应用程序1的Activity A内打开另一个应用程序2的Activity B,这一思路进行写作。流程概括如下:
①Activity A发起一个启动Activity B的请求(对应主流程分析1~2)
②AMS为启动Activity B做准备 (对应主流程分析3~4)
③暂停Activity A(对应主流程分析5~7)
④应用程序1通知AMS完成了暂停操作,AMS处理该消息(对应主流程分析8)
⑤AMS启动一个新的进程,即应用程序2(对应主流程分析9~11)
⑥在新进程内完成Activity B的创建、启动操作(对应主流程分析12~13)

限于文章的篇幅,本文只介绍①~③,剩下的内容会在下一篇文章给出。

时序图

下面先给出与代码分析相一致的时序图,通过该时序图能更好地理解Activity的启动流程,读者可以结合该时序图与下面的代码分析一起看。


Activity启动流程时序图

主流程分析

1、Activity#startActivityForResult()方法:
无论从Launcher或者Activity打开一个新的Activity,都会调用startActivity()方法,而这些重载方法最终都会调用startActivityForResult方法,代码如下:

public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
        @Nullable Bundle options) {
    if (mParent == null) {
        options = transferSpringboardActivityOptions(options);

        //把启动一个Activity的行为交给Instrumentation处理
        Instrumentation.ActivityResult ar =
            mInstrumentation.execStartActivity(
                this, mMainThread.getApplicationThread(), mToken, this,
                intent, requestCode, options);
        if (ar != null) {
            mMainThread.sendActivityResult(
                mToken, mEmbeddedID, requestCode, ar.getResultCode(),
                ar.getResultData());
        }
        if (requestCode >= 0) {
            mStartedActivity = true;
        }

    } //省略部分代码..
}

2、Instrumentation#execStartActivity()方法:
在该方法内,主要是通过ActivityManagerService来启动一个Activity,而该ActivityManagerService是运行在一个独立的进程空间的,它负责整个Android系统内的所有Activity的创建过程。因此,当前APP进程需要与ActivityManagerService进程进行跨进程通信,这就需要借助Binder机制了。

public ActivityResult execStartActivity(
        Context who, IBinder contextThread, IBinder token, Activity target,
        Intent intent, int requestCode, Bundle options) {
    //省略部分代码,只看关键部分..
    //IApplicationThread有点特殊,它是IBinder对象,用于跨进程通信
    IApplicationThread whoThread = (IApplicationThread) contextThread;

    //ActivityMonitor主要配合InstrumentationTest一起使用,用于统计
    //相匹配的Activity启动次数,与APP测试有关,这里省略不谈
    if (mActivityMonitors != null) {
        //....
    }

    try {
        //获取ActivityManagerService代理对象,调用startActivity()方法,
        //这里实际上通过Binder跨进程调用了ActivityManagerService的方法
        int result = ActivityManager.getService()  //2-1代码
            .startActivity(whoThread, who.getBasePackageName(), intent,
                    intent.resolveTypeIfNeeded(who.getContentResolver()),
                    token, target != null ? target.mEmbeddedID : null,
                    requestCode, 0, null, options);
        checkStartActivityResult(result, intent);
    } catch (RemoteException e) {
        throw new RuntimeException("Failure from system", e);
    }
    return null;
}

2-1、我们看看ActivityManager#getService()代码做了什么工作:

public static IActivityManager getService() {
    return IActivityManagerSingleton.get();
}

private static final Singleton<IActivityManager> IActivityManagerSingleton =
        new Singleton<IActivityManager>() {
            @Override
            protected IActivityManager create() {
                final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
                //如果进程不同,则获取一个IActivityManager代理对象
                final IActivityManager am = IActivityManager.Stub.asInterface(b);   
                return am;
            }
        };

显然,这是一个典型的AIDL使用过程。IActivityManager实际上是一个AIDL文件,编译器会帮我们把AIDL文件解析成一个Java文件,也即是IActivityManager.java,通过AIDL的方式我们能方便地实现Binder通信。而Binder通信的内部调用过程,这里不展开来说,我们只关注大体的逻辑即可。上面的IActivityManager.Stub是在编译器生成的一个内部类,而它的asInterface()方法则是根据当前进程是否与IBinder处于同一进程,如果是,则直接返回IActivityManager的实例,否则会返回一个IActivityManager.Stub.Proxy的代理对象。由于我们的App与AMS肯定不是同一进程,所以这里获得的是AMS的远程代理。(可以参考设计模式中的代理模式)

回到代码2-1往下看,在获取了IActivityManager的实例后(实际上是代理对象),会调用它的startActivity(params..)方法,在这个过程中,进行了基于Binder跨进程通信,把一系列的params参数传递给AMS,此时AMS的startActivity(params..)被调用了,我们往下看它的代码。


3、ActivityManagerService#startActivity()
需要注意的是,AMS的代码在/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java 目录下,这是frameworks层的源码,在sdk下是看不到的,所以我们需要下载Android的源码或者在网上查看。(笔者这里通过Android Frameworks源码来查看的,有兴趣的可以自行前往查看)。

当代码运行到这里的时候,我们可以知道以下两个信息:
①从架构的层面来看,已经从应用层来到了frameworks层。
②从进程的层面来看,当前进程已经是AMS所在的进程。

好了,我们继续来分析源码AMS的startActivity()方法的源码:

@Override
public final int startActivity(IApplicationThread caller, String callingPackage,
        Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
        int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
    return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
            resultWho, requestCode, startFlags, profilerInfo, bOptions,
            UserHandle.getCallingUserId());
}


public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
        Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
        int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId,
        boolean validateIncomingUser) {
    enforceNotIsolatedCaller("startActivity");

    userId = mActivityStartController.checkTargetUser(userId, validateIncomingUser,
            Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");

    return mActivityStartController.obtainStarter(intent, "startActivityAsUser")
                                                //ActivityStarter内部有一个Request,封装了请求的具体信息
            .setCaller(caller)                  //设置Caller为IApplicationThread对象,这个实际上是代理对象
            .setCallingPackage(callingPackage)  //设置包名
            .setResolvedType(resolvedType)
            .setResultTo(resultTo)
            .setResultWho(resultWho)
            .setRequestCode(requestCode)
            .setStartFlags(startFlags)
            .setProfilerInfo(profilerInfo)
            .setActivityOptions(bOptions)
            .setMayWait(userId)
            .execute();

}

可以看到,方法的参数已经包含了一系列启动Activity所需要的参数,而在最后又调用了ActivityStartController的方法来获取一个ActivityStarter,并把所有的参数封装到了ActivityStarter.Request内,最后调用ActivityStarter#execute()方法来启动一个Activity的创建过程。

3-1、ActivityStartController#obtainStarter()
我们直接从源码的注释来看看ActivityStartController有什么作用:

/**
 * Controller for delegating activity launches.
 *
 * This class' main objective is to take external activity start requests and prepare them into
 * a series of discrete activity launches that can be handled by an {@link ActivityStarter}. It is
 * also responsible for handling logic that happens around an activity launch, but doesn't
 * necessarily influence the activity start. Examples include power hint management, processing
 * through the pending activity list, and recording home activity launches.
 */
public class ActivityStartController {
     //...

    /**
     * @return A starter to configure and execute starting an activity. It is valid until after
     * {@link ActivityStarter#execute} is invoked. At that point, the starter should be
     * considered invalid and no longer modified or used.
     */
    ActivityStarter obtainStarter(Intent intent, String reason) {
        return mFactory.obtain().setIntent(intent).setReason(reason);
    }
}

从源码注释可以知道,它一个是委派Activity启动的控制器,它管理着一系列的Activity的启动行为,并且承担着Activity启动过程的电量提示管理、Home的启动记录等的工作。但它实际上并不涉及Activity启动的具体逻辑,它把启动的逻辑交给了ActivityStarter来处理了。

3-2、ActivityStarter代码分析

/**
 * Controller for interpreting how and then launching an activity.
 *
 * This class collects all the logic for determining how an intent and flags should be turned into
 * an activity and associated task and stack.
 */
class ActivityStarter {

    //ActivityStartController通过该Factory来获取一个Starter
    static class DefaultFactory implements Factory {

        //对象池内只有3个活跃对象,也即是ActivityStarter被设计成可循环利用的
        private final int MAX_STARTER_COUNT = 3;        

        private SynchronizedPool<ActivityStarter> mStarterPool =
                new SynchronizedPool<>(MAX_STARTER_COUNT);

        //省略部分代码...

        @Override
        public ActivityStarter obtain() {
            ActivityStarter starter = mStarterPool.acquire();

            if (starter == null) {
                starter = new ActivityStarter(mController, mService, mSupervisor, mInterceptor);
            }

            return starter;
        }

        @Override
        public void recycle(ActivityStarter starter) {
            starter.reset(true /* clearRequest*/);
            mStarterPool.release(starter);
        }
    }

    //Request类封装了启动Activity所需要的一切参数
    private static class Request {
        //省略...
    }

    /**
     * Starts an activity based on the request parameters provided earlier.
     * @return The starter result.
     */
    int execute() {
        try {
            if (mRequest.mayWait) {
                return startActivityMayWait(mRequest.caller, mRequest.callingUid,
                        mRequest.callingPackage, mRequest.intent, mRequest.resolvedType,
                        mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
                        mRequest.resultWho, mRequest.requestCode, mRequest.startFlags,
                        mRequest.profilerInfo, mRequest.waitResult, mRequest.globalConfig,
                        mRequest.activityOptions, mRequest.ignoreTargetSecurity, mRequest.userId,
                        mRequest.inTask, mRequest.reason,
                        mRequest.allowPendingRemoteAnimationRegistryLookup);
            }else { 
                //... 
            }
        } finally {
            onExecutionComplete();      //最后,会调用ActivityStartController的对应方法,进行Starter的释放回收
        }
    }

    //省略...
}

ActivityStarter是具体的Activity启动器,它的内部类Request封装了启动Activity的一系列信息,而ActivityStarter被设计成了一个对象池的形式,是可以复用的,因为Android系统可能会频繁地启动Activity,所以启动器设计出复用的形式可以减少开销。当execute()被调用的时候,该启动器便开始执行启动一个Activity的具体流程,即调用startActivityMayWait(params)方法。

我们顺着代码继续往下看,即ActivityStarter#startActivityMayWait()

    private int startActivityMayWait(IApplicationThread caller, int callingUid,
            String callingPackage, Intent intent, String resolvedType,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            IBinder resultTo, String resultWho, int requestCode, int startFlags,
            ProfilerInfo profilerInfo, WaitResult outResult,
            Configuration globalConfig, SafeActivityOptions options, boolean ignoreTargetSecurity,
            int userId, TaskRecord inTask, String reason,
            boolean allowPendingRemoteAnimationRegistryLookup) {
        
        //由于代码很长,这里做了很多删减,只关注主体部分..

        // Collect information about the target of the Intent.
        //这里里面调用了PackageManagerService的方法来解析Intent.
        ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId,0 /* matchFlags */,
            computeResolveFilterUid(callingUid, realCallingUid, mRequest.filterCallingUid));
        //接着将Intent的信息解析为ActivityInfo
        ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);

        synchronized (mService) {
            final ActivityStack stack = mSupervisor.mFocusedStack;
            stack.mConfigWillChange = globalConfig != null
                    && mService.getGlobalConfiguration().diff(globalConfig) != 0;

            final long origId = Binder.clearCallingIdentity(); //设置callingPid和callingUid为当前进程标识

            final ActivityRecord[] outRecord = new ActivityRecord[1];
            //进一步调用startActivity(params..)方法,24个参数的重载方法
            int res = startActivity(caller, intent, ephemeralIntent, resolvedType, aInfo, rInfo,
                    voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid,
                    callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options,
                    ignoreTargetSecurity, componentSpecified, outRecord, inTask, reason,
                    allowPendingRemoteAnimationRegistryLookup);

            Binder.restoreCallingIdentity(origId);     //设置callingPid和callingUid为跨进程调用该方法的进程标识 


            if (outResult != null) {
                outResult.result = res;

                final ActivityRecord r = outRecord[0];

                //根据res来判断Activity的启动状态来做进一步处理
                switch(res) {
                    //Activity正常启动
                    case START_SUCCESS: {
                        mSupervisor.mWaitingActivityLaunched.add(outResult);
                        do {
                            try {
                                mService.wait();
                            } catch (InterruptedException e) {
                            }
                        } while (outResult.result != START_TASK_TO_FRONT
                                && !outResult.timeout && outResult.who == null);
                        if (outResult.result == START_TASK_TO_FRONT) {
                            res = START_TASK_TO_FRONT;
                        }
                        break;
                    }
                    //Activity并不是真正的启动,因为该Intent对应的Activity已在栈顶
                    case START_DELIVERED_TO_TOP: {
                        //省略..

                        break;
                    }
                    //Activity并不是真正的启动,而是把已有的Activity带到了前台
                    case START_TASK_TO_FRONT: {
                        //省略...

                        break;
                    }
                }
            }
            mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(res, outRecord[0]);
            return res;
        }
    }


    /**
     * 经过一系列startActivity()重载方法的调用,最后会调用该方法
     */
    private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
                int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
                ActivityRecord[] outActivity) {
        int result = START_CANCELED;
        try {
            mService.mWindowManager.deferSurfaceLayout();   //通知WindowManager暂停布局

            //进一步调用startActivityUnchecked(params..)方法
            result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
                    startFlags, doResume, options, inTask, outActivity);
        } finally {
            //如果Activity没有启动成功,那么关闭它,否则可能会出现问题
            final ActivityStack stack = mStartActivity.getStack();
            if (!ActivityManager.isStartResultSuccessful(result) && stack != null) {
                stack.finishActivityLocked(mStartActivity, RESULT_CANCELED,
                        null /* intentResultData */, "startActivity", true /* oomAdj */);
            }
            mService.mWindowManager.continueSurfaceLayout();    //通知WindowManager继续布局
        }
        //Activity启动后还有一些工作要处理
        postStartActivityProcessing(r, result, mTargetStack);

        return result;
    }

    /**
     * 该方法处理了Intent的各种flags以及Activity的启动模式
     */
    private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
            ActivityRecord[] outActivity) {
        //初始化信息
        setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,
                voiceInteractor);
        //计算LaunchingTaskFlags,对flag进行合法性处理
        computeLaunchingTaskFlags();
        //如果Task已经结束了,要做出处理,然后获得一个新的Task
        computeSourceStack();

        mIntent.setFlags(mLaunchFlags);

        ActivityRecord reusedActivity = getReusableIntentActivity();    //获取当前Task的Activity

        //...

        //如果Task内已有Activity,结合即将启动Activity的launch mode做出处理
        if (reusedActivity != null) {
            //省略具体处理过程暂不作分析,这里与Activity的启动模式有关
            //..
        }

        //如果Activity的包名不存在,则启动失败
        if (mStartActivity.packageName == null) {
            //省略..

            return START_CLASS_NOT_FOUND;
        }

        //如果即将启动的Activity与栈顶的Activity相同,那么判断是否需要继续启动
        final ActivityStack topStack = mSupervisor.mFocusedStack;
        final ActivityRecord topFocused = topStack.getTopActivity();
        final ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(mNotTop);
        final boolean dontStart = top != null && mStartActivity.resultTo == null
                && top.realActivity.equals(mStartActivity.realActivity)
                && top.userId == mStartActivity.userId
                && top.app != null && top.app.thread != null
                && ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
                || isLaunchModeOneOf(LAUNCH_SINGLE_TOP, LAUNCH_SINGLE_TASK));
        if (dontStart) {
            //省略...

            return START_DELIVERED_TO_TOP;  //这里的返回值表示栈顶就是需要启动的Activity
        }

        //...

        //权限认证
        mService.grantUriPermissionFromIntentLocked(mCallingUid, mStartActivity.packageName,
                mIntent, mStartActivity.getUriPermissionsLocked(), mStartActivity.userId);
        mService.grantEphemeralAccessLocked(mStartActivity.userId, mIntent,
                mStartActivity.appInfo.uid, UserHandle.getAppId(mCallingUid));
        
        //...

        //代码3-3,见下面分析
        mTargetStack.startActivityLocked(mStartActivity, topFocused, newTask, mKeepCurTransition,
                mOptions);

        //mDoResume为true,从函数参数传递进来的
        if (mDoResume) {
            final ActivityRecord topTaskActivity =
                    mStartActivity.getTask().topRunningActivityLocked();
            if (!mTargetStack.isFocusable()
                    || (topTaskActivity != null && topTaskActivity.mTaskOverlay
                    && mStartActivity != topTaskActivity)) {
                mTargetStack.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
                //告诉WindowManager该Activity要做转场动作了
                mService.mWindowManager.executeAppTransition();
            } else {
                
                //代码4-1:第一次启动时,会在这里进行Activity的启动
                mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,
                        mOptions);
            }
        } else if (mStartActivity != null) {
            mSupervisor.mRecentTasks.add(mStartActivity.getTask());
        }

        return START_SUCCESS;
    }

从函数调用栈来看:startActivityMayWait(params..) -> startActivity(params.. ) -> startActivityUnchecked(params..)其中省略了若干个重载方法,这是已经是很深层次的调用栈了,代码也难以理解,因此我们很难对每行代码进行详细的分析也没有这个必要,我们要善于利用奥卡姆剃刀,抽出主干部分进行分析即可,我们的关注点在理解Activity的启动过程及其有关的类的作用,而在此过程有关的Activity launchMode和Flag等可以不做分析。

上面的代码揭示了,一个Activity如果要启动,要结合任务栈Task和Activity的启动模式来进行综合的处理,比如新建一个栈又或者栈内复用等模式的处理。我们来关注上面标注出来的代码3-3,看看它内部做了什么工作。

3-3、ActivityStack#startActivityLocked(params...)

void startActivityLocked(ActivityRecord r, ActivityRecord focusedTopActivity,
        boolean newTask, boolean keepCurTransition, ActivityOptions options) {
    TaskRecord rTask = r.getTask();
    final int taskId = rTask.taskId;

    //这里把Activity添加到Stack的顶部
    if (!r.mLaunchTaskBehind && (taskForIdLocked(taskId) == null || newTask)) {
            // Last activity in task had been removed or ActivityManagerService is reusing task.
            // Insert or replace.
            // Might not even be in.
            insertTaskAtTop(rTask, r);
        }

    TaskRecord task = null;
    if (!newTask) {
        //如果该Task是已存在的,那么要找到这个Task
        //下面的标志位用来表示找到的Task是否是前台Task
        boolean startIt = true;
        //mTaskHistory最后的元素就是最前面的Task
        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
            task = mTaskHistory.get(taskNdx);
            if (task.getTopActivity() == null) {
                // All activities in task are finishing.
                continue;
            }
            if (task == rTask) {
                //要创建的Activity所在的Task不在前台
                if (!startIt) {
                    if (DEBUG_ADD_REMOVE) Slog.i(TAG, "Adding activity " + r + " to task "
                             + task, new RuntimeException("here").fillInStackTrace());
                    r.createWindowContainer();
                    ActivityOptions.abort(options);
                    return;
                }
                break;
            } else if (task.numFullscreen > 0) {
                startIt = false;
            }
        }
    }
    final TaskRecord activityTask = r.getTask();
    task = activityTask;

    if (!isHomeOrRecentsStack() || numActivities() > 0) {
        
        //如果Activity被设置为没有进场动画效果
        if ((r.intent.getFlags() & Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) {
            mWindowManager.prepareAppTransition(TRANSIT_NONE, keepCurTransition);
            mStackSupervisor.mNoAnimActivities.add(r);
        } else {
            //Activity有动画效果
            int transit = TRANSIT_ACTIVITY_OPEN;
            
            //省略...

            //通知WindowManager来准备转场效果
            mWindowManager.prepareAppTransition(transit, keepCurTransition);
            mStackSupervisor.mNoAnimActivities.remove(r);
        }
        
        //如果Activity启动时,它的Task不在前台,确保该Activity是可见的
        if (r.mLaunchTaskBehind) {
            r.setVisibility(true);
            ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
        }

    } 
}

从上面代码的逻辑可以看出,主要是涉及了窗口的处理,即WindowManager,比如该Activity有没有进场动画的标志位等。因为启动一个Activity时,是WindowManager和ActivityManager协同工作的,所以这里主要逻辑是通过通知窗口管理者来进行Window Container的创建。当然,具体逻辑还是很复杂的,这里就不再深究了,让我们回到上一个方法,开始阅读4-1的代码。


4-1、ActivityStackSupervisor#resumeFocusedStackTopActivityLocked(params...)
创建一个Activity,并不只是创建一个可视化的视图而已,它背后任务栈的这一重要的操作,因此打开一个Activity的流程很复杂,其函数的调用栈很深,目前我们来到了ActivityStackSupervisor的地盘,我们来看看这个方法:

boolean resumeFocusedStackTopActivityLocked(
        ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {

    //省略..

    //如果当前Stack位于前台
    if (targetStack != null && isFocusedStack(targetStack)) {
        return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
    }

    //若Stack不在前台
    final ActivityRecord r = mFocusedStack.topRunningActivityLocked();
    if (r == null || !r.isState(RESUMED)) {
        mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
    } else if (r.isState(RESUMED)) {
        // Kick off any lingering app transitions form the MoveTaskToFront operation.
        mFocusedStack.executeAppTransition(targetOptions);
    }


    return false;
}

逻辑还是很简单,ActivityStackSupervisor又把打开Activity的任务交给了一个具体的ActivityStack,因为在之前的代码中我们把一个即将启动的Activity放到了这个Stack里面,现在我们就要对它进行启动工作,我们继续往下来看它的代码。

4-2、ActivityStack#resumeTopActivityUncheckedLocked(params..)

boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
    //如果当前正在重新启动一个Activity,那么跳过
    if (mStackSupervisor.inResumeTopActivity) {
        return false;
    }

    boolean result = false;
    try {
        mStackSupervisor.inResumeTopActivity = true;
        result = resumeTopActivityInnerLocked(prev, options);

        //...
        }
    } finally {
        mStackSupervisor.inResumeTopActivity = false;
    }

    return result;
}

进一步调用了resumeTopActivityInnerLocked(params..),我们来继续看这个方法。

4-3、ActivityStack#resumeTopActivityInnerLocked(params..)

private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
    //下面省略了大量代码,仅保留主要逻辑

    //从当前栈顶取出正在启动的Activity
    final ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */);

    //...

    // mResumedActivity是当前正在运行的Activity,即处于Resumed状态的,
    //而next是我们放到了栈顶正在启动的Activity,注意二者的区别。
    //如果二者相等,那么不做任何改变
    if (mResumedActivity == next && next.isState(RESUMED)
            && mStackSupervisor.allResumedActivitiesComplete()) {
        //...
        return false;
    }

    //如果屏幕关闭了,没有Activity需要启动,并且栈顶的Activity已经暂停,不做改变
    if (shouldSleepOrShutDownActivities()
            && mLastPausedActivity == next
            && mStackSupervisor.allPausedActivitiesComplete()) {
        //...
        return false;
    }

    //...

    //确保该Activity的状态是正确的,从等待停止队列移除等
    mStackSupervisor.mStoppingActivities.remove(next);
    mStackSupervisor.mGoingToSleepActivities.remove(next);
    next.sleeping = false;
    mStackSupervisor.mActivitiesWaitingForVisibleActivity.remove(next);

    //当前有Activity正在执行pause操作,return
    if (!mStackSupervisor.allPausedActivitiesComplete()) {
        //...
        return false;
    }

    //暂停后备堆栈中的所有Activity
    boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, next, false);
    if (mResumedActivity != null) {
        //代码5-1、暂停当前处于Resumed状态的Activity
        pausing |= startPausingLocked(userLeaving, false, next, false);
    }
        
    //与WindowManager交互,确定Activity的启动动画
    boolean anim = true;
    if (prev != null) {
        if (prev.finishing) {
            if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION,
                    "Prepare close transition: prev=" + prev);
            if (mStackSupervisor.mNoAnimActivities.contains(prev)) {
                anim = false;
                mWindowManager.prepareAppTransition(TRANSIT_NONE, false);
            } else {
                mWindowManager.prepareAppTransition(prev.getTask() == next.getTask()
                        ? TRANSIT_ACTIVITY_CLOSE
                        : TRANSIT_TASK_CLOSE, false);
            }
            prev.setVisibility(false);
        }
    } else {
        //...
    }
    mStackSupervisor.mNoAnimActivities.clear();

    ActivityStack lastStack = mStackSupervisor.getLastStack();
    if (next.app != null && next.app.thread != null) {
        //...

    } else {
        //代码8-4
        //该方法实际上是真正启动一个Activity的地方,但这里的调用不会生效
        //因为,该方法的内部会进行一次判断:是否有Activity处于未暂停的状态
        //上面我们跨进程进行了Activity的暂停,在Activity未全部暂停之前,该方法都不会真正被调用。
        //这里的调用应该是适用于这种情况:别的Activity全部处于暂停状态,能直接启动新的Activity了
        mStackSupervisor.startSpecificActivityLocked(next, true, true);
    }
    return true;
}

从上面代码的逻辑来看,主要是先执行5-1的代码,暂停当前处于Resumed状态的Activity,然后在最后真正地去启动当前栈顶就绪的Activity。下面,我们就先来查看怎么处理暂停Activity的逻辑,接着再看怎么处理启动Activity的逻辑。


5-1、ActivityStack#startPausingLocked(params..)

final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping,
        ActivityRecord resuming, boolean pauseImmediately) {
    //省略部分代码...
    ActivityRecord prev = mResumedActivity;

    if (prev == null) {
        if (resuming == null) {
            Slog.wtf(TAG, "Trying to pause when nothing is resumed");
            mStackSupervisor.resumeFocusedStackTopActivityLocked();
        }
        return false;
    }

    if (prev == resuming) {
        Slog.wtf(TAG, "Trying to pause activity that is in process of being resumed");
        return false;
    }

    if (prev.app != null && prev.app.thread != null) {
        try {
            //代码5-2、调用LifecycleManager#scheduleTransaction方法...
            mService.getLifecycleManager().scheduleTransaction(prev.app.thread, prev.appToken,
                    PauseActivityItem.obtain(prev.finishing, userLeaving,
                            prev.configChangeFlags, pauseImmediately));
        } 
    } 

}

通过mService#getLifecycleManager()获得了LifecycleManager,这里的mService就是AMS,而LifecycleManager实际上是类ClientLifecycleManager,它的代码位于/frameworks/base/services/core/java/com/android/server/am/ClientLifecycleManager.java

5-2、ClientLifecycleManager#scheduleTransaction(params..)

/**
 * Schedule a single lifecycle request or callback to client activity.
 * @param client Target client.
 * @param activityToken Target activity token.
 * @param stateRequest A request to move target activity to a desired lifecycle state.
 * @throws RemoteException
 *
 * @see ClientTransactionItem
 */
void scheduleTransaction(@NonNull IApplicationThread client, @NonNull IBinder activityToken,
        @NonNull ActivityLifecycleItem stateRequest) throws RemoteException {
    final ClientTransaction clientTransaction = transactionWithState(client, activityToken,
            stateRequest);
    scheduleTransaction(clientTransaction);
}

void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
    final IApplicationThread client = transaction.getClient();
    transaction.schedule();
    if (!(client instanceof Binder)) {
        // If client is not an instance of Binder - it's a remote call and at this point it is
        // safe to recycle the object. All objects used for local calls will be recycled after
        // the transaction is executed on client in ActivityThread.
        transaction.recycle();
    }
}

上面的逻辑很清晰,先获得了一个ClientTransaction对象,然后再调用它的schedule()方法,最后进行了ClientTransaction对象的回收。ClientTransaction封装了一系列的请求信息,即我们的暂停Activity的所有信息都封装到了它的内部,同时它实现了Parcelable接口,表示可序列化的,这说明它肯定是用于跨进程传输的对象,我们往下看代码。

5-3、ClientTransaction#schedule()
代码文件在/frameworks/base/core/java/android/app/servertransaction/ClientTransaction.java

    /**
     * Schedule the transaction after it was initialized. It will be send to client and all its
     * individual parts will be applied in the following sequence:
     * 1. The client calls {@link #preExecute(ClientTransactionHandler)}, which triggers all work
     *    that needs to be done before actually scheduling the transaction for callbacks and
     *    lifecycle state request.
     * 2. The transaction message is scheduled.
     * 3. The client calls {@link TransactionExecutor#execute(ClientTransaction)}, which executes
     *    all callbacks and necessary lifecycle transitions.
     */
    public void schedule() throws RemoteException {
        mClient.scheduleTransaction(this);
    }

从方法的注释我们可以知道:
①一次请求会先调用ClientTransaction#preExecute(ClientTransactionHandler)
②然后执行这个请求
③接着调用TransactionExecutor#execute(ClientTransaction)

方法里面进行了mClient#scheduleTransaction这一调用,这里的mClient其实就是IApplicationThread,它实际上是一个代理对象,继承了IBinder,表示我们的APP,主要用于跨进程通信。这里实际上是一次跨进程调用,此时,从AMS所在的进程切换到了我们的应用进程。


6-1、IApplicationThread#scheduleTransaction(transaction)
IApplicationThread是ActivityThread的一个内部类,我们从那里寻找它的方法scheduleTransaction(transaction)

public final class ActivityThread extends ClientTransactionHandler {
    //...

    private class ApplicationThread extends IApplicationThread.Stub {
        @Override
        public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
            ActivityThread.this.scheduleTransaction(transaction);
        }

        //...
    }
}

可以看到,在该方法的内部进一步调用了ActivityThread#scheduleTransaction()方法,实际上这里交给了ActivityThread的父类ClientTransactionHandler来处理了。需要注意的是:这里传递过来的ClientTransaction是跨进程通信过程中反序列化生成的对象。

6-2、ClientTransactionHandler#scheduleTransaction(transaction)

public abstract class ClientTransactionHandler {

    // Schedule phase related logic and handlers.

    /** Prepare and schedule transaction for execution. */
    void scheduleTransaction(ClientTransaction transaction) {
        transaction.preExecute(this);  //代码6-3
        sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);  //代码6-4
    }
    //...
}

6-3、ClientTransaction#preExecute(ClientTransactionHandler)
前面5-3有提到过会先调用preExecute方法,这里得到了印证。我们来看ClientTransactionpreExecute方法。

    public void preExecute(android.app.ClientTransactionHandler clientTransactionHandler) {
        if (mActivityCallbacks != null) {
            final int size = mActivityCallbacks.size();
            for (int i = 0; i < size; ++i) {
                mActivityCallbacks.get(i).preExecute(clientTransactionHandler, mActivityToken);
            }
        }
        if (mLifecycleStateRequest != null) {
            mLifecycleStateRequest.preExecute(clientTransactionHandler, mActivityToken);
        }
    }

这里主要是进行各种回调的调用,就不继续展开说了。

6-4、ActivityThread#sendMessage(params..)
继续执行代码6-4,这里调用了sendMessage方法,在ClientTransactionHandler中该方法被标注为抽象方法,具体实现是在ActivityThread内。实际上,ActivityThread内部的H继承了Handler,用于处理各种消息。这也就是主线程的消息循环。我们直接来看H的代码:

public final class ActivityThread extends ClientTransactionHandler {
    //...

    class H extends Handler {

        //一系列消息常量的定义..
        public static final int EXECUTE_TRANSACTION = 159;

        public void handleMessage(Message msg) {
            //根据不同的消息类型进行不同的处理
            switch (msg.what) {
                case EXECUTE_TRANSACTION:
                    final ClientTransaction transaction = (ClientTransaction) msg.obj;
                    mTransactionExecutor.execute(transaction);
                    if (isSystem()) {
                        // Client transactions inside system process are recycled on the client side
                        // instead of ClientLifecycleManager to avoid being cleared before this
                        // message is handled.
                        transaction.recycle();
                    }
                    break;
            }
        }

    }
}

这里把处理的逻辑交由给TransactionExecutor来完成,然后进行ClientTransaction的回收。


7-1、TransactionExecutor#execute(ClientTransaction)
TransactionExecutor可以理解为一个执行器,专门用于执行各种ClientTransaction

    /**
     * Resolve transaction.
     * First all callbacks will be executed in the order they appear in the list. If a callback
     * requires a certain pre- or post-execution state, the client will be transitioned accordingly.
     * Then the client will cycle to the final lifecycle state if provided. Otherwise, it will
     * either remain in the initial state, or last state needed by a callback.
     */
    public void execute(ClientTransaction transaction) {
        final IBinder token = transaction.getActivityToken();
        log("Start resolving transaction for client: " + mTransactionHandler + ", token: " + token);

        executeCallbacks(transaction);

        executeLifecycleState(transaction);
        mPendingActions.clear();
        log("End resolving transaction");
    }

方法内部首先执行executeCallbacks(transaction),由于对于Pause状态来说,并没有添加任何callback,所以我们先省略该方法,接着来看executeLifecycleState(transaction)

7-2、TransactionExecutor#executeLifecycleState(transaction)

/** Transition to the final state if requested by the transaction. */
private void executeLifecycleState(ClientTransaction transaction) {
    //根据之前的代码逻辑,这里的lifecycleItem实际上是PauseLifecycleItem.
    final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest(); 
    
    final IBinder token = transaction.getActivityToken();
    final ActivityClientRecord r = mTransactionHandler.getActivityClient(token);

    //把ActivityClientRecord的状态切换到target状态,这里是pause,表示把Activity切换到暂停状态
    cycleToPath(r, lifecycleItem.getTargetState(), true /* excludeLastState */);

    // Execute the final transition with proper parameters.
    lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
    lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
}

private void cycleToPath(ActivityClientRecord r, int finish,
        boolean excludeLastState) {
    final int start = r.getLifecycleState();
    //计算从start->finish的状态变化路径
    //比如:onCreate->onResume的变化路径有:onStart、onResume等(不包括初始状态)
    //该方法很简单,读者可以自行去看
    final IntArray path = mHelper.getLifecyclePath(start, finish, excludeLastState);
    performLifecycleSequence(r, path);  //把该Activity的状态沿着这个路径进行切换
}

/** 该方法把Activity的状态沿着路径进行切换 */
private void performLifecycleSequence(ActivityClientRecord r, IntArray path) {
    final int size = path.size();
    for (int i = 0, state; i < size; i++) {
        state = path.get(i);
        switch (state) {
            case ON_CREATE:
                mTransactionHandler.handleLaunchActivity(r, mPendingActions,
                        null /* customIntent */);
                break;
            case ON_START:
                mTransactionHandler.handleStartActivity(r, mPendingActions);
                break;
            case ON_RESUME:
                mTransactionHandler.handleResumeActivity(r.token, false /* finalStateRequest */,
                        r.isForward, "LIFECYCLER_RESUME_ACTIVITY");
                break;
            case ON_PAUSE:
                mTransactionHandler.handlePauseActivity(r.token, false /* finished */,
                        false /* userLeaving */, 0 /* configChanges */, mPendingActions,
                        "LIFECYCLER_PAUSE_ACTIVITY");
                break;
            case ON_STOP:
                mTransactionHandler.handleStopActivity(r.token, false /* show */,
                        0 /* configChanges */, mPendingActions, false /* finalStateRequest */,
                        "LIFECYCLER_STOP_ACTIVITY");
                break;
            case ON_DESTROY:
                mTransactionHandler.handleDestroyActivity(r.token, false /* finishing */,
                        0 /* configChanges */, false /* getNonConfigInstance */,
                        "performLifecycleSequence. cycling to:" + path.get(size - 1));
                break;
            case ON_RESTART:
                mTransactionHandler.performRestartActivity(r.token, false /* start */);
                break;
            default:
                throw new IllegalArgumentException("Unexpected lifecycle state: " + state);
        }
    }
}

上面的代码逻辑还是很清晰的,主要是先计算出Activity由当前状态切换到目标状态所需要走的路径,然后遍历这个路径上的每一个状态,把Activity依次切换到该状态,当遍历到最后一个状态时,Activity便完成了状态的切换。上面代码的最后,又把具体逻辑交给了mTransactionHandler来处理,实际上这里的mTransactionHandler就是ActivityThread,它继承了TransactionHandler。因此我们到ActivityThread里面找相应的方法。

7-3、ActivityThread#handlePauseActivity(params..)
因为我们的目标状态是Pause,所以会调用到handlePauseActivity()方法。

@Override
public void handlePauseActivity(IBinder token, boolean finished, boolean userLeaving,
        int configChanges, PendingTransactionActions pendingActions, String reason) {
    ActivityClientRecord r = mActivities.get(token);
    if (r != null) {
        if (userLeaving) {
            performUserLeavingActivity(r);
        }

        r.activity.mConfigChangeFlags |= configChanges;
        performPauseActivity(r, finished, reason, pendingActions);

        // Make sure any pending writes are now committed.
        if (r.isPreHoneycomb()) {
            QueuedWork.waitToFinish();
        }
        mSomeActivitiesChanged = true;
    }
}

/**
 * Pause the activity.
 * @return Saved instance state for pre-Honeycomb apps if it was saved, {@code null} otherwise.
 */
private Bundle performPauseActivity(ActivityClientRecord r, boolean finished, String reason,
        PendingTransactionActions pendingActions) {
    //Honeycomb版本之前的APP在暂停的时候会保存状态
    final boolean shouldSaveState = !r.activity.mFinished && r.isPreHoneycomb();
    if (shouldSaveState) {
        callActivityOnSaveInstanceState(r);
    }

    performPauseActivityIfNeeded(r, reason);

    // Notify any outstanding on paused listeners
    ArrayList<OnActivityPausedListener> listeners;
    synchronized (mOnPauseListeners) {
        listeners = mOnPauseListeners.remove(r.activity);
    }
    int size = (listeners != null ? listeners.size() : 0);
    for (int i = 0; i < size; i++) {
        listeners.get(i).onPaused(r.activity);
    }

    //省略...

    return shouldSaveState ? r.state : null;
}

private void performPauseActivityIfNeeded(ActivityClientRecord r, String reason) {
    if (r.paused) {
        // You are already paused silly...
        return;
    }

    try {
        r.activity.mCalled = false;
        mInstrumentation.callActivityOnPause(r.activity);
        
    } catch (Exception e) {
        //省略..
    }
    r.setState(ON_PAUSE);
}

经过层层的调用,我们最后发现调用到了mInstrumentation.callActivityOnPause(r.activity),这个Instrumentation在上面的代码解析中也有碰到过,我们话不多说直接来看它的实现:

/**
 * Perform calling of an activity's {@link Activity#onPause} method.  The
 * default implementation simply calls through to that method.
 * 
 * @param activity The activity being paused.
 */
public void callActivityOnPause(Activity activity) {
    activity.performPause();
}

到这里已经很明朗了,已经调用到了Activity#performPause方法,即:

final void performPause() {
    mDoReportFullyDrawn = false;
    mFragments.dispatchPause(); //把暂停事件分发给Fragment,以触发它们暂停
    mCalled = false;
    onPause();          //调用onPause,这是我们业务逻辑层经常接触的一个生命周期方法
    writeEventLog(LOG_AM_ON_PAUSE_CALLED, "performPause");
    mResumed = false;

    //...
}

到现在,已经触发了onPause()这个生命周期方法,整个暂停的流程就已经完成了。那么当一个Activity暂停了,下一步就是执行新Activity的创建流程了。

那么在client端怎么通知server端要执行启动Activity的操作呢?
让我们把目光定位到代码7-2的executeLifecycleState(transaction)方法内部,在方法的最后,会依次执行executepostExecute方法,而这里的lifecycleItem实际上就是PauseActivityItem

7-4、PauseActivityItem#postExecute()

@Override
public void postExecute(ClientTransactionHandler client, IBinder token,
        PendingTransactionActions pendingActions) {
    if (mDontReport) {
        return;
    }
    try {
        //通知AMS,Activity已经暂停完毕,是时候启动Activity了
        ActivityManager.getService().activityPaused(token);
    } catch (RemoteException ex) {
        throw ex.rethrowFromSystemServer();
    }
}

这里直接通过Binder跨进程通信,告诉AMS该Activity已经暂停了,AMS可以开始启动原本打算启动的Activity了。到这一步,APP内的工作暂时完成了,此时进程又会切换到AMS进程内。在开始下一步代码的阅读之前,我们需要小结一下代码6~7客户端所做的所有工作。

小结:APP一直都在进行着主线程的消息循环,等待新的消息的到来。此时,AMS通过Binder跨进程调用了ApplicationThread的某个方法(如上面的scheduleTransaction),该方法运行在客户端的一条子线程上,然后该方法通过Handler机制,切换到了主线程。此时在主线程执行handleMessage方法,进而调用到具体的某一方法。其中,涉及到Activity生命周期的信息、操作被封装到了ClientTransaction内部,而具体的每一个生命周期则由ActivityLifecycleItem的子类来表述。在一个操作完成之后(比如上面的pause操作),可能会通知AMS进行下一步操作。然后客户端继续进行主线程的消息循环,等待AMS的下一次通知。

更多阅读
Android源码探究:Activity启动流程完全解析(下)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,847评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,208评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,587评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,942评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,332评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,587评论 1 218
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,853评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,568评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,273评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,542评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,033评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,373评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,031评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,073评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,830评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,628评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,537评论 2 269

推荐阅读更多精彩内容