前言

本文的启动流程是同一个app内的Activity启动流程,所以没有涉及到新建进程的过程,后面再进行补充。另外源码非常庞大,函数参数经常10个以上,所以会用省略号代替。另外为了函数流程更加直观我使用Class.Method(……)来表示。

环境准备

1.源代码一份,我使用的Android 7.1.2。重点是可以有真机或者模拟器调试
2.使用Android studio将源码导入,导入方法百度上很多。下次写篇导入的文章,主要有些注意事项,比如android.R的导入。
3.找到自己的想要调试的方法,设置好断点,开始调试即可。
4.调试过程中可能涉及到handler,多线程之前的关系,自己要区分好。

第一阶段

先上张流程图:

Android Activity是否运行 android activity 启动流程_Android 源码调试


第一阶段是AMS先pause正在显示的Activity

//初始化package&activity信息
    ActivityStarter.startActivityMayWait(......)
    //权限判断,voiceSession判断,等等
    ActivityStarter.startActivityLocked(......)
    //初始化Starter,计算launcher flag,
    //其实就是找到可用的ActivityStack,可用/新建TaskRecord,
    ActivityStarter.startActivityUnchecked(......)
    //把将要启动的Activity“压入task栈顶”,调整task到“栈顶”
    ActivityStack.startActivityLocked(......)
    //修改mFocusedActivity
    ActivityManagerService.setFocusedActivityLocked
    //把将要启动Activiy所在的ActivityStack移动到“栈顶”
    ActivityStackSupervisor.moveActivityStackToFront
    //开始Resume Activity
    ActivityStack.resumeTopActivityInnerLocked(......)
    //找到当前focused的ActivityStack
    ActivityStackSupervisor.pauseBackStacks(......)
    //这里的this(ActivityStack)是将要pause的activity所在的ActivityStack, 
    ActivityStack.startPausingLocked(......, false/* dontWait*/){
        ......
        ActivityRecord prev = mResumedActivity;
        ......
        mResumedActivity = null;
        //把stack中的,mPausingActivity 赋值为 mResumedActivity
        mPausingActivity = prev;
        mLastPausedActivity = prev;
        mLastNoHistoryActivity = ......;
        //修改mPausingActivity状态为PAUSING
        prev.state = ActivityState.PAUSING;
        .......
        if (prev.app != null && prev.app.thread != null) {
            ......
            //这里向其实是向app请求prev activity pause。此时app端是binder服务端
            //app调完onPause后又会向ActivityMangerService回调activityPause
            prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,
                        userLeaving, prev.configChangeFlags, dontWait);
            ......
        }
        ......
        if (dontWait /* false */ ) {
                // If the caller said they don't want to wait for the pause, then complete
                // the pause now.
                completePauseLocked(false, resuming);
                return false;

            } else {
                // Schedule a pause timeout in case the app doesn't respond.
                // We don't give it much time because this directly impacts the
                // responsiveness seen by the user.
                // 走这里,可以提早返回,而不用等prev pause ok
                // 这样发起startActivity的app不会阻塞
                Message msg = mHandler.obtainMessage(PAUSE_TIMEOUT_MSG);
                msg.obj = prev;
                prev.pauseTime = SystemClock.uptimeMillis();
                mHandler.sendMessageDelayed(msg, PAUSE_TIMEOUT /* 500ms */);
                if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Waiting for pause to complete...");
                return true;
            }
    }

好了, 第一阶段的代码解析到这,你们猜猜现在现在线程运行状态是怎样的?

1. 调用startActivity的app client使用的binder线程, 拿到拿到了AMS的句柄

Android Activity是否运行 android activity 启动流程_sed_02


2.ActivityManager线程是在等锁释放的,所以这个PAUSE_TIMEOUT_MSG的消息还处理不了

Android Activity是否运行 android activity 启动流程_sed_03


到这里大家是否有疑问:

1.AMS已经调用了schedulePauseActivity

2.但是从Thread maps上看,被pause的app进程没有通过binder向AMS回调通知activity pause的状态

因为目标app的startActivity流程还没执行完。AMS只是向binder驱动请求了这个过程,目标app的binder主线程还在执行startActivity,自然没办法处理AMS来的其他消息,注意这里app是Server。继续调试让startActivity的binder过程完成。那么问题又来了

1.PAUSE_TIMEOUT_MSG先执行

2.目标app的先把pause的状态binder到AMS

正常是2先执行

但是调试的时候,是1先来到,如下图:

Android Activity是否运行 android activity 启动流程_sed_04


Android Activity是否运行 android activity 启动流程_Activity启动_05


竟然是先PAUSE_TIMEOUT_MSG,但是当你了解handler的delay机制就知道为啥了

机制:度娘正常的结果我是调试出来的,如下调试方法:

首先在message处理的地方加上断点打印

Android Activity是否运行 android activity 启动流程_sed_06


在binder回调的地方加上

Android Activity是否运行 android activity 启动流程_ide_07


结果如下:

Android Activity是否运行 android activity 启动流程_sed_08

第二阶段

从目标app把pause的状态binder到AMS的过程开始

ActivityManagerService.activityPaused(IBinder token){
    final long origId = Binder.clearCallingIdentity();
        synchronized(this) {
            ActivityStack stack = ActivityRecord.getStackLocked(token);
            if (stack != null) {
                //这里是通过token拿到的ActivityStack
                stack.activityPausedLocked(token, false);
            }
        }
        Binder.restoreCallingIdentity(origId);
    }
ActivityStack.activityPausedLocked(IBinder token, boolean timeout){
        final ActivityRecord r = isInStackLocked(token);
        if (r != null) {
            //去掉PAUSE_TIMEOUT_MSG消息
            mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
            if (mPausingActivity == r) {
                ......
                completePauseLocked(true, null);
                return;
            } else {
                ......
            }
        ......
    }
ActivityStack.completePauseLocked(Boolean resumeNext /* true */,......){
        //第一阶段的将要pause的activity
        ActivityRecord prev = mPausingActivity;
        if (prev != null) {
            final boolean wasStopping = prev.state == ActivityState.STOPPING;
            prev.state = ActivityState.PAUSED;
            if (prev.finishing /* 这里为false */) {
                //进入fainish流程
                prev = finishCurrentActivityLocked(......);
            } else if (prev.app != null) {
                ......
            }
        }

         if (resumeNext) {
             //获取顶层stack
            final ActivityStack topStack = mStackSupervisor.getFocusedStack();
            if (!mService.isSleepingOrShuttingDownLocked() /* true */) {
                mStackSupervisor.resumeFocusedStackTopActivityLocked(topStack, prev, null);
            }else{
                ......
            }
        }
        ......
    }
ActivityStackSupervisor.resumeFocusedStackTopActivityLocked(......) {
        if (targetStack != null && isFocusedStack(targetStack)) {
            return targetStack.resumeTopActivityUncheckedLocked(......);
        }
        ......
        return false;
    }
ActivityStack.resumeTopActivityUncheckedLocked(......){
        ......
        result = resumeTopActivityInnerLocked(prev, options);
        ......
    }
//又来到这个方法了,不过这次不会走pause流程
    ActivityStack.resumeTopActivityInnerLocked(......){
        ......
        boolean pausing = mStackSupervisor.pauseBackStacks(......);
        //第一阶段置null了
        if (mResumedActivity/*null*/ != null) {
            pausing |= startPausingLocked(......);
        }
        if (pausing /* false */) {
            ......
        }else if(mResumedActivity/*null*/ == next && next.state == ActivityState.RESUMED &&
                mStackSupervisor.allResumedActivitiesComplete()){
             ......
         }
         //一系列令人窒息的操作
        ......
        //这两个都为null
        if (next.app != null && next.app.thread != null) {
            //一顿操作
            ......
        }else{
            ......
            //重点
            mStackSupervisor.startSpecificActivityLocked(next, true, true);
        }
    }
ActivityStackSupervisor.startSpecificActivityLocked(......){
        // Is this activity's application already running?
        // 如果是启动一个未启动的app,那么这里为null
        ProcessRecord app = mService.getProcessRecordLocked(r.processName,
                r.info.applicationInfo.uid, true);
        r.task.stack.setLaunchTime(r);
        if (app != null && app.thread != null) {
            ......
            realStartActivityLocked(r, app, andResume, checkConfig);
            return;
        }
    }
ActivityStackSupervisor.realStartActivityLocked(......){
        //保证所有的activity没有resumed的
        if (!allPausedActivitiesComplete()) {
            // While there are activities pausing we skipping starting any new activities until
            // pauses are complete. NOTE: that we also do this for activities that are starting in
            // the paused state because they will first be resumed then paused on the client side.
            if (DEBUG_SWITCH || DEBUG_PAUSE || DEBUG_STATES) Slog.v(TAG_PAUSE,
                    "realStartActivityLocked: Skipping start of r=" + r
                    + " some activities pausing...");
            return false;
        }
        //超级窒息的操作
        ......
        //重点来了,还记得之前的说的嘛,这个pause的binder还没结束,所以这个操作在app端不会立即执行
        //但是有个前提:启动的不是另外一个app进程的activity
        app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
                    System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),
                    new Configuration(task.mOverrideConfig), r.compat, r.launchedFromPackage,
                    task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results,
                    newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo);

         ......
         if (andResume) {
            // As part of the process of launching, ActivityThread also performs
            // a resume.
            stack.minimalResumeActivityLocked(r);
        } 
        ......
    }
//到这里马上进入下一个阶段了
    ActivityStack.minimalResumeActivityLocked(ActivityRecord r) {
        //修改activity的状态
        r.state = ActivityState.RESUMED;
        mResumedActivity = r;
        r.task.touchActiveTime();
        mRecentTasks.addLocked(r.task);
        //这里和pause差不多,也会发一个IDLE_TIMEOUT_MSG超时广播
        completeResumeLocked(r);
        mStackSupervisor.checkReadyForSleepLocked();
        setLaunchTime(r);
    }

第三阶段

第三阶段比较简单,AMS等待启动的Activity 通过binder回调activityIdle,而这个过程是通过IdleHandler来实现

//Activity端的实现,
    ActivityThread.handleResumeActivity(......){
        ......
        if (!r.onlyLocalRequest) {
                r.nextIdle = mNewActivities;
                mNewActivities = r;
                if (localLOGV) Slog.v(
                    TAG, "Scheduling idle handler for " + r);
                Looper.myQueue().addIdleHandler(new Idler());
            }
            r.onlyLocalRequest = false;
        ......
    }
private class Idler implements MessageQueue.IdleHandler {
        @Override
        public final boolean queueIdle() {
            ......
            IActivityManager am = ActivityManagerNative.getDefault();
            ......
            am.activityIdle(a.token, a.createdConfig, stopProfiling);
            ......
            return false;
        }
    }
//来到AMS
    ActivityManagerService.activityIdle(......){
        ......
        mStackSupervisor.activityIdleInternalLocked(token, false, config);
        ......
    }
//这里不详细分析了
    activityIdleInternalLocked(.......){
        ......
        mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
        ......
    }

总结一下:
1. 启动一个Activity的流程往往涉及到至少一个app和AMS的交互
2. 每个Activity都有一个“token”来标识自己
3. 启动哪个Activity由ActivityStarter控制
4. 所有的ActivityStack由ActivityStackSupervisor管理
5. 一个ActivityStack由多个TaskRecord组成
6. 一个TaskRecord由多个ActivityRecord组成
7. Android N上一共有5种Stask,各有各的用途
8. Android中对Activity的管理其实并不是真正意义上的stack
9. Binder真的很重要,Android的灵魂,建议先熟悉了Binder机制再看代码
10. AMS源码调用关系复杂,但是每个函数基本都干自己的事情,每个函数最重要的通信桥梁不是函数参数,而是一些很重要全局变量。很多函数会因为某个全局变量的值不一样会有不一样的结果。
11. Android系统对耗电量真的放的很宽,正常来说函数调用越多,耗电越多。