Skip to content

Activity启动流程调用栈分析

Mr.wu edited this page Feb 28, 2018 · 2 revisions

基于Android 7.0源码分析,分析activity启动流程

涉及到的类

frameworks/base/services/core/java/com/android/server/am/
  - ActivityManagerService.java
  - ActivityStarter.java
  - ActivityStackSupervisor.java
  - ActivityStack.java
  - ActivityRecord.java
  - ProcessRecord.java

frameworks/base/core/java/android/app/
  - IActivityManager.java
  - ActivityManagerNative.java (内含AMP)
  - ActivityManager.java
  
  - IApplicationThread.java
  - ApplicationThreadNative.java (内含ATP)
  - ActivityThread.java (内含ApplicationThread)
  
  - ContextImpl.java

1、启动流程调用链

Activity.startActivity
Activity.startActivityForResult
Instrumentation.execStartActivity
AMP.startActivity
AMN.onTransact
AMS.startActivity
ActivityStarter.startActivityMayWait
ActivityStarter.startActivityLocked
ActivityStarter.startActivityUnchecked
ActivityStackSupervisor.resumeFocusedStackTopActivityLocked
ActivityStack.resumeTopActivityUncheckedLocked
ActivityStack.resumeTopActivityInnerLocked

ActivityStarter是新添加的类,Google的注释明确了这个类的作用是解析Intent和flag(启动模式等参数),来决定如何启动Activity和调整任务栈。

if (mResumedActivity != null) {
            pausing |= startPausingLocked(userLeaving, false, next, dontWaitForPause);
        }

Pause正在显示的Activity

ActivityStack.startPausingLocked 
ApplicationThread.schedulePauseActivity
ActivityThread.H.handleMessage(PAUSE_ACTIVITY)
ActivityThread.handlePauseActivity
ActivityThread.performPauseActivity
//ActivityThread.callCallActivityOnSaveInstanceState//有需要时,SaveInstacneState会在这里调用
ActivityThread.performPauseActivityIfNeeded
Instrumentation.callActivityOnPause
Activity.performPause
Activity.onPause

ActivityStack.startPausingLocked通过mResumedActivity的IApplicationThread Binder来让流程进入当前应用的ActivityThread处理Pause操作。

final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping,
            ActivityRecord resuming, boolean dontWait) {
    ...
    ActivityRecord prev = mResumedActivity;
    if (prev.app != null && prev.app.thread != null) {
            try {
                mService.updateUsageStats(prev, false);
                //
prev.app.thread分别是ActivityRecordProcessRecordIApplicationThread
                prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,
                        userLeaving, prev.configChangeFlags, dontWait);
            } ...
    }
    ...
}

ApplicationThread中的方法都会通过消息转发给ActivityThread的Handler做处理。 更多关于ActivityThread的信息会在后面启动进程的时候提到。

关于onStop的执行 只要Activity完成onPause,之后下一个Activity就可以启动了,因此Activity onStop的执行放到ActivityThread的IdleHandler中,当ActivityThread的MessageQueue处理完队列中的消息后,再去执行Activity.onStop,提高应用启动的效率。

提示:完成onPause是启动下一个Activity的必要条件,因此onPause中最好不要执行耗时的操作。

调用栈如下:

MessageQueue.next//完成队列中所有消息处理后
ActivityThread.Idler.queueIdle
ActivityManagerNative.activityIdle
ActivityManagerService.activityIdle
ActivityStackSupervisor.activityIdleInternalLocked
ActivityStack.stopActivityLocked
ApplicationThread.scheduleStopActivity
ActivityThread.H.sendMessage(STOP_ACTIVITY)
ActivityThread.H.handleMessage
ActivityThread.handleStopActivity
ActivityThread.performStopActivityInner
//ActivityThread.callCallActivityOnSaveInstanceState
Activity.performStop
Activity.onStop

ActivityThread中IdleHandler的定义:

//ActivityThread.java
private class Idler implements MessageQueue.IdleHandler {
        @Override
        public final boolean queueIdle() {
            ActivityClientRecord a = mNewActivities;
            ...
            if (a != null) {
                mNewActivities = null;
                IActivityManager am = ActivityManagerNative.getDefault();
                ActivityClientRecord prev;
                do {
                    if (a.activity != null && !a.activity.mFinished) {
                        try {
                            //MessageQueue目前灭有待处理消息,告知ams执行idle处理
                            am.activityIdle(a.token, a.createdConfig, stopProfiling);
                            a.createdConfig = null;
                        } catch (RemoteException ex) {
                            throw ex.rethrowFromSystemServer();
                        }
                    }
                    prev = a;
                    a = a.nextIdle;
                    prev.nextIdle = null;
                } while (a != null);
            }
            return false;
        }
    }

完成onPause是启动下一个Activity的必要条件,因此onPause中最好不要执行耗时的操作。

Activity Paused执行完成后

//activity pause完成

ActivityThread.handlePauseActivity
ActivityManagerNative.getDefault().activityPaused
ActivityManagerService.activityPaused
ActivityStack.activityPausedLocked
ActivityStack.completePauseLocked
ActivityStackSupervisor.resumeFocusedStackTopActivityLocked
ActivityStack.resumeTopActivityUncheckedLocked
ActivityStack.resumeTopActivityInnerLocked
ActivityStackSupervisor.startSpecificActivityLocked

可以注意到,ActivityStack.resumeTopActivityInnerLocked方法就是前面发起Pause Activity的地方,现在因为旧的Activity已经Paused,因此进入下一步,如果进程存在则启动Activity,否则需要新建进程。

void startSpecificActivityLocked(ActivityRecord r,
            boolean andResume, boolean checkConfig) {
        ProcessRecord app = null;
        ...
        //如果进程和ApplicationThread都存在,那么直接启动Activity
        if (app != null && app.thread != null) {
            try {
                ...
                realStartActivityLocked(r, app, andResume, checkConfig);
                return;
            } 
            ...
        }
        //进程不存在则需要新建
        mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
                "activity", r.intent.getComponent(), false, false, true);
    }

启动目标Activity所属的进程 如需要则启动新进程,如进程已存在,那么就不需要再重复创建了,流程上会直接进入创建Activity并执行onCreate的ActivityStackSupervisor.realStartActivityLocked方法,当中的处理也会确保Application和相关类在Activity启动前就存在。

创建进程的调用栈:

ActivityManagerService.startProcessLocked
ActivityManagerService.startProcessLocked
Process.start
Process.startViaZygote//openZygoteSocketIfNeeded获取socket读写管道
Process.zygoteSendArgsAndGetResult

ActivityManagerService向Process.start指定了要启动的Class为 "android.app.ActivityThread",因此在进程创建之后,会直接在其中执行ActivityThread.main方法

    private final void startProcessLocked(ProcessRecord app, String hostingType,
            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
            ...
            boolean isActivityProcess = (entryPoint == null);
            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
            Process.ProcessStartResult startResult = Process.start(entryPoint,
                    app.processName, uid, uid, gids, debugFlags, mountExternal,
                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
                    app.info.dataDir, entryPointArgs);
            ...
}  

ActivityThread.main ActivityThread可以等同于我们常说的应用“主线程”,但ActivityThread本身并不是线程,至少它不是继承自Thread的。准确来说,应用的主线程只负责执行ActivityThread的main方法。

main方法启动了一个Looper循环,无限的等待接收外部发送过来的Message,执行对应的处理。 因此可以说Android应用完全是靠消息驱动的。

Google之所以将主线程称为UI线程,就是要想强调主线程最好只用来做UI操作,这样能避免耗时操作引发ANR。

//ActivityThread.java
    public static void main(String[] args) {
        ...
        Process.setArgV0("<pre-initialized>");

        Looper.prepareMainLooper();

        ActivityThread thread = new ActivityThread();
        thread.attach(false);
        if (sMainThreadHandler == null) {
            sMainThreadHandler = thread.getHandler();
        }

        Looper.loop();

        throw new RuntimeException("Main thread loop unexpectedly exited");
    }

前面可以看到,系统指定了Zygote在创建进程后直接执行ActivityThread.main方法,这个方法启动了一个Looper循环,因此主线程中的所有操作都会通过这个Looper来分发给ActivityThread的Handler来执行。 前面的分析也能看到,AMS能管理应用的基础就是跨进程+消息,ActivityThread的所有操作都是在主线程中执行的(包括Application和Activity的生命周期),所以说应用千万不能在主线程执行耗时操作,否则就是触发ANR。

IApplicationThread与AMS attach并创建Application 如果目标Application已经存在,那么这一节也可以忽略。

ActivityThread.main在执行looper前,先将Application binder注册给AMS,随后将完成ApplicationContext , Instrumentation , 和Application实例的创建,并执行Application的onCreate方法

ActivityThread.main
ActivityThread.attach
ActivityManagerNative.attachApplication
ActivityManagerService.attachApplication
ApplicationThread.bindApplication
ActivityThread.H.sendMessage(BIND_APPLICATION)
ActivityThread.H.handleMessage

ActivityThread.handleBindApplication
//创建AppContext,Instrumentation和Application实例,并执Application.onCreate
{ContextImpl.createAppContext -> new Instrumentation -> LoadApk.makeApplication -> Instrumentation.callApplicationOnCreate}

//完成attach
ActivityStackSupervisor.attachApplicationLocked

创建Activity并执行onCreate 完成Application attach后,ActivityStackSupervisor终于要通知ApplicationThread去启动新的Activity。过程会创建新的Activity, Context,并将一些Activity需要用到的数据和实例attach给Activity,最后由Instrumentation来调用Activity.onCreate方法

ActivityStackSupervisor.attachApplicationLocked
ActivityStackSupervisor.realStartActivityLocked
ApplicationThread.scheduleLaunchActivity
ActivityThread.H.sendMessage(LAUNCH_ACTIVITY)
ActivityThread.H.handleMessage
ActivityThread.handleLaunchActivity

ActivityThread.performLaunchActivity
//创建Activity -> 创建Context -> 将Activity与Context/app等信息关联
{createBaseContextForActivity -> Activity.attach}

Instrumentation.callActivityOnCreate
Activity.performCreate
Activity.onCreate

ActivityRecord并没有继承于Binder。 但ActivityRecord的成员变量appToken的数据类型为Token,Token继承于IApplicationToken.Stub。

appToken:system_server进程通过调用scheduleLaunchActivity()将appToken传递到App进程,

调用createActivityContext(),保存到ContextImpl.mActivityToken 调用activity.attach(),保存到Activity.mToken;

Start 和 Resume 在Activity.onCreate执行完成之后,ActivityThread.performLaunchActivity方法会继续发起Activity的onStart和onResume。

ActivityThread.performLaunchActivity
Activity.performStart
Instrumentation.callActivityOnStart
Activity.onStart
//Instrumentation.callActivityOnRestoreInstanceState //onStart结束后可能会调用OnRestoreInstanceState

//回到ActivityThread.handleLaunchActivity
ActivityThread.handleResumeActivity
ActivityThread.performResumeActivity
Activity.performResume
Instrumentation.callActivityOnResume
Activity.onResume

至此,新的Activity已经在屏幕中可见了。

小结 要点:

  1. ActivityManagerService是一个Binder,注册到SystemServer。
  2. ApplicationThread是ActivityThread的内部类,是一个实现了IActivityThread的Binder。AMS通过ApplicationThread对应用进行控制。
  3. onPause执行完成后,由ActivityThread的IdleHandler触发onStop的执行
  4. 只有目标应用的进程不存在时才会重新创建进程(Process)

start_activity_process

参考:http://blog.csdn.net/wilschan0201/article/details/73888004

http://gityuan.com/2016/03/12/start-activity/

Home

Android 开发录

-深入理解LayoutInflater.inflate()的参数

计算机网络原理

数据库

Java 垃圾回收机制

Java 开发录

面试

搭建翻墙shadowsocks 教程

其他

Clone this wiki locally