Android6.0 Activity启动流程解析

API版本 23
本例从Launcher 启动一个 应用开始分析

# Activity.startActivityForResult

public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
                                   @Nullable Bundle options) {
    if (mParent == null) {
        options = transferSpringboardActivityOptions(options);
        // 调用 Instrumentation.execStartActivity()
        Instrumentation.ActivityResult ar =
                mInstrumentation.execStartActivity(
                        this, mMainThread.getApplicationThread(), mToken, this,
                        intent, requestCode, options);
        //...
    } else {
        //...
    }
}
  • mMaintThread -> 类型为 ActivityThread, 每个进程都有一份
  • mToken -> 类型为 IBinder, 指向 ActivityRecordBinder 本地对象. 每一个已经启动的 Activity 组件在 ActivityManagerService(以下简称ASM) 中都有一个对应的 ActivityRecord 对象, 用来维护对应的 Activity 组件的运行状态及信息.
  • ActivityRecord 为重要变量, 可以把他认为是 Activity 即可.

略过中间部分, 直接来到 ActivityStackSupervisor.startActivityMayWait 方法, Binder通信, 不是本文重点.
ActivityStackSupervisor 整个系统中只有一个, 可以认为是管理全局 Activity 组件的类就可以.

# ActivityStackSupervisor.startActivityMayWait

final 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 config,
                               Bundle options, boolean ignoreTargetSecurity, int userId,
                               IActivityContainer iContainer, TaskRecord inTask) {
    
    // 是否指明了 Component, 可以省去 Intent匹配搜索
    boolean componentSpecified = intent.getComponent() != null;

    // 查询满足条件的 Activity, 和 PKMS 交互
    ActivityInfo aInfo =
        resolveActivity(intent, resolvedType, startFlags, profilerInfo, userId);

    synchronized (mService) {
        // 获取调用者的 pid, 和 uid
        final int realCallingPid = Binder.getCallingPid();
        final int realCallingUid = Binder.getCallingUid();
        // ...

        final ActivityStack stack;
        if (container == null || container.mStack.isOnHomeDisplay()) {
            stack = mFocusedStack;
        } else {
            stack = container.mStack;
        }

        int res = startActivityLocked(caller, intent, resolvedType, aInfo,
                                      voiceSession, voiceInteractor, resultTo, resultWho,
                                      requestCode, callingPid, callingUid, callingPackage,
                                      realCallingPid, realCallingUid, startFlags, options, 
                                      ignoreTargetSecurity, componentSpecified, null, 
                                      container, inTask);
        
        //...
        return res;
    }
}
  • 根据安装后的信息, 查询 Activity 信息.

# ActivityStackSupervisor. startActivityLocked

final int startActivityLocked(IApplicationThread caller,
                              Intent intent, String resolvedType, ActivityInfo aInfo,
                              IVoiceInteractionSession voiceSession, IVoiceInteractor 
                              voiceInteractor, IBinder resultTo, String resultWho, int 
                              requestCode, int callingPid, int callingUid, String 
                              callingPackage, int realCallingPid, int realCallingUid, int 
                              startFlags, Bundle options, boolean ignoreTargetSecurity, 
                              boolean componentSpecified, ActivityRecord[] outActivity,
                              ActivityContainer container, TaskRecord inTask) {
    // caller 调用者即Launcher ApplicationThreadProxy
    // aInfo 即将启动的Activity信息
    // resultTo 调用者的 ActivityRecord$Token
    
    int err = ActivityManager.START_SUCCESS;
    
    // 第一步
    ProcessRecord callerApp = null;
        if (caller != null) {
            // 根据caller 获取调用者进程信息即Launcher进程信息
            callerApp = mService.getRecordForAppLocked(caller);
            if (callerApp != null) {
                // 得到这个调用者的 pid 和 uid.
                callingPid = callerApp.pid;
                callingUid = callerApp.info.uid;
            } else {
                err = ActivityManager.START_PERMISSION_DENIED;
            }
        }
    //...
    
    // 描述调用者 Activity即Launcher
    ActivityRecord sourceRecord = null;
    // 描述接收调用结果的 Activity, 本例不接收结果
    ActivityRecord resultRecord = null;
    if (resultTo != null) {
        // 根据 resultTo 获取 Launcher的ActivityRecord
        sourceRecord = mSupervisor.isInAnyStackLocked(resultTo);
        if (sourceRecord != null) {
            // requestCode 默认传入 -1, 所以这里 resultRecord 为空
            if (requestCode >= 0 && !sourceRecord.finishing) {
                resultRecord = sourceRecord;
            }
        }
    }
    
    final int launchFlags = intent.getFlags();
    if ((launchFlags & Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 && sourceRecord != null) {
        // 如果存在这个标志位FLAG_ACTIVITY_FORWARD_RESULT, 
        // 那么就需要修改 接受调用结果的Activity, resultRecord, 与本例无关
    }
    
    // 一堆跳转验证, 不能解析Intent, 没找到Activity, 等等

    if (err != ActivityManager.START_SUCCESS) {
        // 如果中间出错, 并且接收结果的 resultRecord 不为空, 返回RESULT_CANCELED
        if (resultRecord != null) {
            resultStack.sendActivityResultLocked(-1,
                                                 resultRecord, resultWho, requestCode,
                                                 Activity.RESULT_CANCELED, null);
        }
        ActivityOptions.abort(options);
        return err;
    }
    
    //...
    // 创建ActivityRecord, 用来描述即将启动的 Activity
    ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,
                                          intent, resolvedType, aInfo,
                                          mService.mConfiguration, resultRecord,
                                          resultWho, requestCode, componentSpecified,
                                          voiceSession != null, mSupervisor, container, 
                                          options, sourceRecord);
    
    //...
    err = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor, startFlags, true, options, inTask);
    
    //...
    return err;
}
  • 每个应用程序的进程都使用一个 ProcessRecord 来描述, 并且保存在 AMS 内部.
  • 权限验证, 解析 intent 后是否找到了对应的 Activity
  • 创建了即将启动页面的 ActivityRecord 对象

中间略过了比较多的步骤, 例如启动 pendingActivity 集合中的 Activity , 是否允许切换App等等. 我们只走主线, 后面代码可能连 ... 也不会标出来了.

# ActivityStackSupervisor.startActivityUnchecked

final int startActivityUncheckedLocked(final ActivityRecord r, 
                                       ActivityRecord sourceRecord,
                                       IVoiceInteractionSession voiceSession, 
                                       IVoiceInteractor voiceInteractor, int startFlags,
                                       boolean doResume, Bundle options, 
                                       TaskRecord inTask) {
    // r 描述即将启动的 ActivityRecord
    // sourceRecord 描述调用者的 ActivityRecord
    // doResume true
    
    // 处理启动模式
    final boolean launchSingleTop = r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP;
    final boolean launchSingleInstance = r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE;
    final boolean launchSingleTask = r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK;
    // 当存在结果接收者并且, 标志 FLAG_ACTIVITY_NEW_TASK时, 返回 RESULT_CANCELED
    if (r.resultTo != null && (launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0
        && r.resultTo.task.stack != null) {
        r.resultTo.task.stack.sendActivityResultLocked(-1, r.resultTo, r.resultWho, 
                                                       r.requestCode, 
                                                       Activity.RESULT_CANCELED, null);
        r.resultTo = null;
    }   
    
    boolean addingToTask = false;
    TaskRecord reuseTask = null;
    // 根据启动模式标志 FLAG_ACTIVITY_NEW_TASK
    if (inTask == null) {
        if (sourceRecord == null) {
            //...
        } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
            launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
        } else if (launchSingleInstance || launchSingleTask) {
            launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
        }
    }
    ActivityInfo newTaskInfo = null;
    Intent newTaskIntent = null;
    ActivityStack sourceStack;
    boolean movedHome = false;
    ActivityStack targetStack;
    intent.setFlags(launchFlags);
    
    if (((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
         (launchFlags & Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
        || launchSingleInstance || launchSingleTask) {
        // ...
        // 根据flag判断启动模式, 另开文章讨论
    }
    
    // 上面一堆 flag 判断, 是为了决定 Activity 该存放在哪个栈里
    if (r.packageName != null) {
        // 原焦点Stack, 本例为表示桌面的 ActivityStack
        ActivityStack topStack = mFocusedStack;
        // 正在顶部运行的 Activity 即 Launcher
        ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(notTop);
        // 如果正在启动的活动与当前位于顶部的活动相同,考虑 singleTop
        if (top != null && r.resultTo == null) {
            if (top.realActivity.equals(r.realActivity) && top.userId == r.userId) {
                // ...
                // 处理singleTop
            }
        }
    }

    boolean newTask = false;
    boolean keepCurTransition = false;
    TaskRecord taskToAffiliate = launchTaskBehind && sourceRecord != null ?
        sourceRecord.task : null;

    if (r.resultTo == null && inTask == null && !addingToTask
        && (launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
        newTask = true;
        // 获取ActivityStack, 如果没有就创建
        targetStack = computeStackFocus(r, newTask);
        // 将targetStack 移至顶部, 
        // mFocusedStack赋值为targetStack, 变更了焦点Stack
        // mLastFocusedStack赋值为原 ActivityStack
        targetStack.moveToFront("startingNewTask");

        // 给即将启动的ActivityRecord, 设置TaskRecord
        if (reuseTask == null) {
            // createTaskRecord() 会创建TaskRecord
            // 并添加到 targetStack 中的 mTaskHistory中
            r.setTask(targetStack.createTaskRecord(getNextTaskId(),
                                                   newTaskInfo != null ? newTaskInfo 
                                                   r.info, newTaskIntent != null ? 
                                                   newTaskIntent : intent,
                                                   voiceSession, voiceInteractor, 
                                                   !launchTaskBehind /* toTop */), 
                      taskToAffiliate);
        } else {
            r.setTask(reuseTask, taskToAffiliate);
        }

    }
    
    // mLastPausedActivity 置空
    targetStack.mLastPausedActivity = null;
    targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options);
}
  • TaskRecord 表示栈, 它里面保存了在该栈中保存的 Activity 集合.
  • ActivityStack 用于管理 TaskRecord , 一般情况下只有表示桌面的 ActivityStack , 和应用程序的 ActivityStack, 多屏幕状态下可能会不一样, 没有验证.

桌面的 ActivityStack 存有两个 TaskRecord , 分别存着 LauncherRecentActivity

ActivityStack , TaskRecord , ActivityRecord 三者的关系如图:

ActivityStack, TaskRecord, ActivityRecord关系图.png

  • 上面的代码用一句话概括就是, 根据配置判断是否要新建栈 .

# ActivityStack.startActivityLocked

final void startActivityLocked(ActivityRecord r, boolean newTask, 
                               boolean keepCurTransition, ActivityOptions options) {
    TaskRecord rTask = r.task;
    final int taskId = rTask.taskId;
    TaskRecord task = null;
    
    if (!newTask) {
        // 如果不是新建Task栈, 则找到合适的栈
    }
    task = r.task;
    
    // 将要启动的ActivityRecord 添加到TastRecord.mActivityes 集合的最尾部
    task.addActivityToTop(r);    
    // 添加了新的Activity, 所以需要给 ActivityRecord的变量frontOfTask重新赋值
    // 该变量在后面会用到, 表示是否是 TaskRecord集合中第一个元素, 也就是根元素
    task.task.setFrontOfTask();
    //...
    
    // 上面传过来 true
    if (doResume) {
        mStackSupervisor.resumeTopActivitiesLocked(this, r, options);
    }
}
  • 找到合适的栈, 并且置顶

跳过两个简单方法, 直接定位到下面方法

# ActivityStack.resumeTopActivityLocked

private boolean resumeTopActivityInnerLocked(ActivityRecord prev, Bundle options) {
    // prev, 即将启动的ActivityRecord
    // (只限于该步骤, 多处调用该方法, 那时的prev意义不一样)

    // 获取该ActivityStack, TaskRecord集合中最后一个元素
    // TaskRecord中 Activity集合中最后一个非finishing的 ActivityRecord
    // 因为在上面分析中, TaskRecord已经添加到 mTaskHistory的尾部, 并且
    // ActivityRecord 也添加到对应的 TaskRecord当中, 所以这里 next 等同于prev
    final ActivityRecord next = topRunningActivityLocked(null);
    
    final TaskRecord prevTask = prev != null ? prev.task : null;
    next.delayedResume = false;
    if (mResumedActivity == next && next.state == ActivityState.RESUMED &&
        mStackSupervisor.allResumedActivitiesComplete()) {
        // 如果顶部Activity状态为RESUMED, 返回
        return false;
    }

    mStackSupervisor.mStoppingActivities.remove(next);
    mStackSupervisor.mGoingToSleepActivities.remove(next);
    next.sleeping = false;
    mStackSupervisor.mWaitingVisibleActivities.remove(next);
    
    //...
    
    // 是否等待 pause
    // FLAG_RESUME_WHILE_PAUSING, 这个标志位可以不等待 PAUSE, 进行 RESUME
    // 我们讨论一般情况, 该变量为 false
    boolean dontWaitForPause = (next.info.flags&ActivityInfo.FLAG_RESUME_WHILE_PAUSING) != 0;

    // 从名字中可以看出, 对backStack执行Pause
    // backStack指的是非FocusStack, 因为上面已经将焦点Stack变更了
    // 这里backstack指的是桌面的ActivitStack
    boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, true, dontWaitForPause);
    
    // mResumedActivity是当前ActivityStack的成员变量
    // 在本次例中, 新建了ActivityStack, 所以mResumedActivity为空
    if (mResumedActivity != null) {
        pausing |= startPausingLocked(userLeaving, false, true, dontWaitForPause);
    }

    // 上面对两个ActivityStack只要有一个成功执行了pause, 那么这里直接返回
    // 并且整个系统进程调用完毕, Launcher进程被挂起的线程恢复
    if (pausing) {
        // ...
        return true;
    }

    //************重要的分割线************
    // 其实下面有很重要的方法, 但是因为上面已经返回了.
    // 所以下面暂时就不用管, 待会会执行到下面的代码
    
    // ...
}
  • 找到 Resume 状态的 ActivityLauncher .
  • 找到后调用 ActivityStack.startPausingLocked

看一下两个决定 pausing 变量的两个函数

# ActivityStackSupervisor.startPausingLocked

boolean pauseBackStacks(boolean userLeaving, boolean resuming, boolean dontWait) {
    boolean someActivityPaused = false;
    for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
        ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
        for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
            final ActivityStack stack = stacks.get(stackNdx);
            // isFrontStack() 判断是否是焦点Stack
            if (!isFrontStack(stack) && stack.mResumedActivity != null) {
                // 本例中Launcher点击图标, 进入应用
                // Launcher处在的ActivityStack为backStack
                // mResumedActivity 为 Launcher
                // 调用 startPausingLocked
                someActivityPaused |= stack.startPausingLocked(userLeaving, false, 
                                                               resuming, dontWait);
            }
        }
    }
    return someActivityPaused;
}

# ActivityStack.startPausingLocked

final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping, 
                                 boolean resuming, boolean dontWait) {
    //...
    // 表示 Launcher
    ActivityRecord prev = mResumedActivity;
    // 将mResumedActivity置空
    mResumedActivity = null;
    mPausingActivity = prev;
    mLastPausedActivity = prev;
    // 状态变更为 PAUSING
    prev.state = ActivityState.PAUSING;
    // 返回即将启动的ActivityRecord
    final ActivityRecord next = mStackSupervisor.topRunningActivityLocked();
    if (prev.app != null && prev.app.thread != null) {
        // 查询 LauncherActivity是否存在
        // 走到应用进程调用Pause方法
        // 在 handlePauseActivity() 中, 在返回到系统进程
        // 调用 activityPaused() **重点**
        prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,
                                              userLeaving, prev.configChangeFlags, 
                                              dontWait);
    } else {
        mPausingActivity = null;
        mLastPausedActivity = null;
        mLastNoHistoryActivity = null;
    }
    if (mPausingActivity != null) {
        if (dontWait) {
            // 特殊标志位, 不等待Pause执行Resume, 不讨论
            completePauseLocked(false);
            return false;
        } else {
            // 走到这个分支
            Message msg = mHandler.obtainMessage(PAUSE_TIMEOUT_MSG);
            msg.obj = prev;
            prev.pauseTime = SystemClock.uptimeMillis();
            // 在ServiceThread中执行 activityPausedLocked **重点**
            mHandler.sendMessageDelayed(msg, PAUSE_TIMEOUT); // 500ms
            return true;
        }
    } else {
        return false;
    }
}
  • mResumedActivity 置空, 所以现在系统中是没有正在 RESUMEActivity , 所以如果下次进入 resumeTopActivityInnerLocked , 因为没有要 PAUSEActivity , 所以不会返回 .

  • 以下两个方法最终会掉用同一个方法.

    • ActivityThread.schedulePauseActivity
    • 系统进程中给 ServiceThread 发送了 PAUSE_TIMEOUT_MSG 消息

# ActivityThread. handlePauseActivity

private void handlePauseActivity(IBinder token, boolean finished,
                                 boolean userLeaving, int configChanges, boolean dontReport) {
    ActivityClientRecord r = mActivities.get(token);
    if (r != null) {
        if (userLeaving) {
            performUserLeavingActivity(r);
        }

        // 调用 Activity 的 onPause() 方法
        performPauseActivity(token, finished, r.isPreHoneycomb());

        // Tell the activity manager we have paused.
        if (!dontReport) {
            try {
                // 调用 AMS 的 activityPaused()
                ActivityManagerNative.getDefault().activityPaused(token);
            } catch (RemoteException ex) {
            }
        }
        mSomeActivitiesChanged = true;
    }
}
  • 执行了 LauncheronPause 后, 紧接着回调给 AMS , AMS.activityPaused() -> ActivityStack.activityPausedLocked(),

接下来在看在系统进程发送的 PAUSE_TIMEOUT_MSG 消息.

# ActivityStackHandler.handleMessage

public void handleMessage(Message msg) {
    //...
    case PAUSE_TIMEOUT_MSG: {
        ActivityRecord r = (ActivityRecord)msg.obj;
        synchronized (mService) {
            // 同样调用了, activityPausedLocked, 但是在发送该消息时是延迟了500秒
            activityPausedLocked(r.appToken, true);
        }
    } break;
}
  • 系统中很多类似这种超时消息, 确保在进程通信卡住时, 该方法也能够正确调用

# ActivityStack.activityPausedLocked

final void activityPausedLocked(IBinder token, boolean timeout) {
    // 本例中Launcher
    final ActivityRecord r = isInStackLocked(token);
    if (r != null) {
        // 移除Handler消息, 有可能是Handler进到这, 
        // 有可能是应用进程通过系统进程进入这里, 不同的是参数timeout
        mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
        if (mPausingActivity == r) {
            // 进入该分支
            completePauseLocked(true);
        } else {
            if (r.finishing && r.state == ActivityState.PAUSING) {
                finishCurrentActivityLocked(r, FINISH_AFTER_VISIBLE, false);
            }
        }
    }
}
  • 这个函数没什么好讲的, 移除了PAUSE_TIMEOUT_MSG消息

# ActivityStack.completePauseLocked

private void completePauseLocked(boolean resumeNext) {
    ActivityRecord prev = mPausingActivity;
    if (prev != null) {
        prev.state = ActivityState.PAUSED;
        if (prev.finishing) {
            // 立即结束
            prev = finishCurrentActivityLocked(prev, FINISH_AFTER_VISIBLE, false);
        } else if (prev.app != null) {
            if (prev.configDestroy) {
            // ...
            } else if (!hasVisibleBehindActivity() || mService.isSleepingOrShuttingDown()) 
            {
                // 添加到StoppingActivity集合中, 过会会执行onStop
                mStackSupervisor.mStoppingActivities.add(prev);
                // 如果StoppingActivity集合中已经堆积了3个以上要停止的活动
                // 或者该Activity是TaskRecord栈中最后一个, 
                // 发送IDLE_NOW_MSG消息, 该方法中会执行 onStop, onDestroy等
                // 文字最后解析
                if (mStackSupervisor.mStoppingActivities.size() > 3 ||
                    prev.frontOfTask && mTaskHistory.size() <= 1) {
                    mStackSupervisor.scheduleIdleLocked();
                } else {
                    mStackSupervisor.checkReadyForSleepLocked();
                }
            }
        } else {
            prev = null;
        }
    }
    if (resumeNext) {
        final ActivityStack topStack = mStackSupervisor.getFocusedStack();
        // 继续调用 resumeTopActivitiesLocked
        if (!mService.isSleepingOrShuttingDown()) {
            mStackSupervisor.resumeTopActivitiesLocked(topStack, prev, null);
        } else {
            mStackSupervisor.checkReadyForSleepLocked();
            ActivityRecord top = topStack.topRunningActivityLocked(null);
            if (top == null || (prev != null && top != prev)) {
                mStackSupervisor.resumeTopActivitiesLocked(topStack, null, null);
            }
        }
    }
}
  • 发送 IDLE_NOW_MSG 消息后, Launcher 因为是栈中唯一一个 Activity , 所以会执行 onStop() , 但这不是重点. 最后会贴上执行 onStop() 的代码.
  • 调用了 resumeTopActivitiesLocked

接着看 resumeTopActivitiesLocked 后半段代码

private boolean resumeTopActivityInnerLocked(ActivityRecord prev, Bundle options) {

    // 要启动的 Activity
    final ActivityRecord next = topRunningActivityLocked(null);
    //... Transition相关
    // nextActivity是否已经存在
    if (next.app != null && next.app.thread != null) {
        // 本例中Launcher点击启动, 所以不存在, 走另外一个分支
        //...
        // 状态置位 RESUME
        next.state = ActivityState.RESUMED;
        mResumedActivity = next;
        // 应用进程触发 onResume()
        // 执行后回调系统进程 activityResumed
        next.app.thread.scheduleResumeActivity(next.appToken, next.app.repProcState,
                                               mService.isNextTransitionForward(), 
                                               resumeAnimOptions);
        try{
            //...
        } catch (Exception e) {
            // 这里会try catch一下, 如果在nextActivity存在的情况下执行失败
            // 执行 else 时的方法
            mStackSupervisor.startSpecificActivityLocked(next, true, false);
        }
    } else {
        // nextActivity不存在, 需要创建
        mStackSupervisor.startSpecificActivityLocked(next, true, true);
    }   
}
  • 判断要启动的 Activity 是否存在, 如果已经存在的情况下, 只需要调用 onResume() 恢复页面就可以了, 本例走不存在的分支

# ActivityStackSupervisor.startSpecificActivityLocked

void startSpecificActivityLocked(ActivityRecord r,
                                 boolean andResume, boolean checkConfig) {

    // 根据 uid 和 processName查询是否存在进程
    // 进程没有被杀死就能查询的到
    ProcessRecord app = mService.getProcessRecordLocked(r.processName,
                                                        r.info.applicationInfo.uid, true);
    if (app != null && app.thread != null) {
        // 查询到了
        try {
            if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
                || !"android".equals(r.info.packageName)) {
                // 确保不是框架的一部分
                app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode,
                               mService.mProcessStats);
            }
            // 通知该进程启动目标Activity
            // 虽然本例不进入这个分支, 但请记住这个方法
            // 创建完成进程后依然调用此方法
            realStartActivityLocked(r, app, andResume, checkConfig);
            return;
        } catch (RemoteException e) {
        }
    }

    // 没有查询到, 需要创建应用进程
    mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
                                "activity", r.intent.getComponent(), false, false, true);
}
  • 本例中进程不存在, 需要创建

新建进程暂时还没有了解到, 从 Gityuan 博客的图中了解一下.

图片来自 Gityuan 博客

新建进程完成后
ActivityThread.main() -> AMS.attachApplication() -> AMS.attachApplicationLocked()

# ActivityManagerService.attachApplicationLocked

private final boolean attachApplicationLocked(IApplicationThread thread,
                                              int pid) {
    //...
    // 如果此应用程序记录仍附加到先前的进程,立即清理它。
    if (app.thread != null) {
        handleAppDiedLocked(app, true, true);
    }
    //...
    // 创建进程时, 发送了创建进程超时的消息, 移除它
    mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
    // 获取该进程中的 ContentProvider
    List<ProviderInfo> providers = normalMode ? 
        generateApplicationProvidersLocked(app) : null;

    // 系统进程 -> 应用进程
    // 进程初次创建时, 进程信息为空, 
    // 这个方法将告诉该进程具体信息
    thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
                           profilerInfo, app.instrumentationArguments, 
                           app.instrumentationWatcher, 
                           app.instrumentationUiAutomationConnection, testMode, 
                           enableOpenGlTrace, isRestrictedBackupMode || !normalMode, 
                           app.persistent, new Configuration(mConfiguration), app.compat,
                           getCommonServicesLocked(app.isolated),
                           mCoreSettingsObserver.getCoreSettingsLocked());
    if (normalMode) {
        try {
            // 启动Activity
            if (mStackSupervisor.attachApplicationLocked(app)) {
                didSomething = true;
            }
        } catch (Exception e) {
            badApp = true;
        }
    }
   
    // 启动Service
    if (!badApp) {
        try {
            didSomething |= mServices.attachApplicationLocked(app, processName);
        } catch (Exception e) {
            badApp = true;
        }
    }
    // 启动广播?
    if (!badApp && isPendingBroadcastProcessLocked(pid)) {
        try {
            didSomething |= sendPendingBroadcastsLocked(app);
        } catch (Exception e) {
            badApp = true;
        }
    }
    // ...
    // 出错
    if (badApp) {
        handleAppDiedLocked(app, false, true);
        return false;
    }
    return true
}
  • 这个方法需要两个分支都需要跟进, thread.bindApplication()mStackSupervisor.attachApplicationLocked(app)
  • 对清单文件中的Service和常驻广播进行处理

# activityThread.handleBindApplication

// AMS调用bindAppliation, 走到应用进程发消息给主线程, 并调用该方法
private void handleBindApplication(AppBindData data) {
    //...
    // 设置进程名称, 刚创建进程时名字为 <pre_initialized>
    Process.setArgV0(data.processName);
    
    //获取LoadedApk对象
    data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
    
    //...

    if (data.instrumentationName != null) {
        // 正常情况下为空
    } else {
        mInstrumentation = new Instrumentation();
    }
    
    // 创建Application
    // 创建ContextImpl, 并执行Application的attachBaseContext,
    Application app = data.info.makeApplication(data.restrictedBackupMode, null);
    
    // 安装本Package中携带的ContentProvider
    if (!data.restrictedBackupMode) {
        List<ProviderInfo> providers = data.providers;
        if (providers != null) {
            installContentProviders(app, providers);
            mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000);
        }
    }
    // 执行Application的 onCreate()
    mInstrumentation.callApplicationOnCreate(app);
}
  • 创建 Application , 安装 ContentProvider , Application 的生命周期方法

bindApplication 这条分支走完了.

ActivitySupervisor. attachApplicationLocked

boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
    final String processName = app.processName;
    boolean didSomething = false;
    // ...
    // 找到焦点Stack的栈顶Activity
    ActivityRecord hr = stack.topRunningActivityLocked(null);
    if (hr != null) {
        if (hr.app == null && app.uid == hr.info.applicationInfo.uid
            && processName.equals(hr.processName)) {
            try {
                // 和上面已经存在进程情况下一样的方法
                if (realStartActivityLocked(hr, app, true, true)) {
                    didSomething = true;
                }
            } catch (RemoteException e) {}
        }
    }
    return didSomething;
}
  • 进程及进程的 Application 创建完毕, 该启动对应的 Activity 了.

# ActivityStackSupervisor.realStartActivityLocked

final boolean realStartActivityLocked(ActivityRecord r,
            ProcessRecord app, boolean andResume, boolean checkConfig)
            throws RemoteException {
    int idx = app.activities.indexOf(r);
    if (idx < 0) {
        app.activities.add(r);
    }
    
    // 系统进程 -> 应用进程
    // 调用 ApplicationThread 的 scheduleLaunchActivity() 方法
    // 依次调用 onCreate, onStart, onResume
    app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
                                      System.identityHashCode(r), r.info, new 
                                      Configuration(mService.mConfiguration),
                                      new Configuration(stack.mOverrideConfig), r.compat, 
                                      r.launchedFromPackage,
                                      task.voiceInteractor, app.repProcState, r.icicle, 
                                      r.persistentState, results,
                                      newIntents, !andResume, 
                                      mService.isNextTransitionForward(), profilerInfo);
    
    //...
    // 本例中 andResume 为true
    if (andResume) {
        // 不容忽视的方法
        stack.minimalResumeActivityLocked(r);
    }   
}
  • 回到应用进程调用, scheduleLaunchActivity 这个方法会依次调用 Activity 的, onCreate , onStart , onResume .
  • 还有重要的一点是 stack.minimalResumeActivityLocked(r) 这个方法不容忽视, 等启动代码分析完后在分析它.

ApplicationThread.scheduleLaunchActivity -> ActivityThread.handleLaunchActivity

# ActivityThread.handleLaunchActivity

private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    //...
    // 创建 Activity, 并调用 onCreate, onStart
    Activity a = performLaunchActivity(r, customIntent);
    if (a != null) {
        //...
        // 调用 onResume
        handleResumeActivity(r.token, false, r.isForward,
                             !r.activity.mFinished && !r.startsNotResumed);
    }
}

# ActivityThread. performLaunchActivity

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
                Application app = r.packageInfo.makeApplication(false, mInstrumentation);
    activity.attach(appContext, this, getInstrumentation(), r.token,
                    r.ident, app, r.intent, r.activityInfo, title, r.parent,
                    r.embeddedID, r.lastNonConfigurationInstances, config,
                    r.referrer, r.voiceInteractor);
    // 这个变量控制是否调用了Activity.onCreate(), 
    // Activity.onCreate()里会把mCalled赋为true
    activity.mCalled = false;
    if (r.isPersistable()) {
        mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
    } else {
        // 调用onCreate()
        mInstrumentation.callActivityOnCreate(activity, r.state);
    }
    // 没有调用父类的onCreate , 抛异常
    if (!activity.mCalled) {
        throw new SuperNotCalledException(
            "Activity " + r.intent.getComponent().toShortString() +
            " did not call through to super.onCreate()");
    }
    if (!r.activity.mFinished) {
        // 调用 onStart()
        activity.performStart();
        r.stopped = false;
    }
}

# ActivityThread. handleResumeActivity

final void handleResumeActivity(IBinder token,
                                boolean clearHide, boolean isForward, boolean reallyResume) {
    // ...
    // 调用Activity的 onResume 方法
    ActivityClientRecord r = performResumeActivity(token, clearHide);
    if (r != null) {
        // ...
        if (!r.onlyLocalRequest) {
            r.nextIdle = mNewActivities;
            mNewActivities = r;
            // 主线发送闲置消息, ***重要***
            Looper.myQueue().addIdleHandler(new Idler());
        }
        r.onlyLocalRequest = false;
        // Tell the activity manager we have resumed.
        if (reallyResume) {
            try {
                // 回调AMS, resume调用完毕, 只是修改两个变量不探讨
                ActivityManagerNative.getDefault().activityResumed(token);
            } catch (RemoteException ex) {
            }
        }
    } 
    // ...
}
  • Looper.myQueue().addIdleHandler(new Idler()) 先记住该方法

# ActivityStack.minimalResumeActivityLocked

void minimalResumeActivityLocked(ActivityRecord r) {
    r.state = ActivityState.RESUMED;
    r.stopped = false;
    mResumedActivity = r;
    r.task.touchActiveTime();
    mRecentTasks.addLocked(r.task);
    // 看下面
    completeResumeLocked(r);
    mStackSupervisor.checkReadyForSleepLocked();
    setLaunchTime(r);
}

private void completeResumeLocked(ActivityRecord next) {
    next.idle = false;
    next.results = null;
    next.newIntents = null;

    // 设置空闲超时
    // 发送给 AMS 进程的handler一个空闲超时的消息
    // 在 应用进程的 Handler在空闲时, 会调用 系统进程的 activityIdle()
    // 在该方法中执行 finish或stop等方法, 具体总结后在摘代码
    mStackSupervisor.scheduleIdleTimeoutLocked(next);
}

至此上面记录的三个重要函数在重新列一下

  • 系统进程 -> mStackSupervisor.scheduleIdleLocked()
  • 应用进程 -> Looper.myQueue().addIdleHandler(new Idler())
  • 系统进程 -> mStackSupervisor.scheduleIdleTimeoutLocked(next)

这三个方法最终都会调用 ActivitySupervisor.activityIdleInternalLocked
最后一个方法会执行延迟10秒发送, 这种方法在上述代码中提过一次

# ActivitySupervisor.activityIdleInternalLocked

final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,
                                                Configuration config) {
    // 要执行Stop的集合
    ArrayList<ActivityRecord> stops = null;
    // 要执行Finish的集合
    ArrayList<ActivityRecord> finishes = null;
    ArrayList<UserState> startingUsers = null;
    boolean booting = false;
    boolean activityRemoved = false;

    ActivityRecord r = ActivityRecord.forTokenLocked(token);
    if (r != null) {
        // 移除超时消息
        mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
    }

    // mStoppingActivities集合中, 将即将可见的Activity除外
    stops = processStoppingActivitiesLocked(true);
    NS = stops != null ? stops.size() : 0;
    if ((NF = mFinishingActivities.size()) > 0) {
        finishes = new ArrayList<>(mFinishingActivities);
        mFinishingActivities.clear();
    }

    // Stop any activities that are scheduled to do so but have been
    // waiting for the next one to start.
    for (int i = 0; i < NS; i++) {
        r = stops.get(i);
        final ActivityStack stack = r.task.stack;
        if (stack != null) {
            if (r.finishing) {
                // 如果要执行 stop的状态为finish, 立即结束
                stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false);
            } else {
                // 否则执行 stop
                stack.stopActivityLocked(r);
            }
        }
    }

    // Finish any activities that are scheduled to do so but have been
    // waiting for the next one to start.
    for (int i = 0; i < NF; i++) {
        r = finishes.get(i);
        final ActivityStack stack = r.task.stack;
        if (stack != null) {
            // 如果有要结束的Activity, 结束掉
            activityRemoved |= stack.destroyActivityLocked(r, true, "finish-idle");
        }
    }

    // 如果有被移除的 Activity, 执行resumeTopActivitiesLocked
    if (activityRemoved) {
        resumeTopActivitiesLocked();
    }

    return r;
}

至此整个Activity启动流程结束了.
需要注意的是 resumeTopActivitiesLocked() , 只要操作 Activity , 就会有 Pause 的界面和 Resume 的界面, 一般情况下 Resume 会等待 Pause 完后执行 . 所以调用 resumeTopActivitiesLocked 的地方特别多, 要注意在哪里返回, 在哪里继续执行 .

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

推荐阅读更多精彩内容