Android7.0 Activity启动流程调用栈分析

关于Activity的启动流程详细说明的文章已经多如牛毛,而且流程中经常会出现超长的方法,实在没有必要再每个方法代码都罗列一次,这里只做调用栈的记录,从宏观上理解这个过程。

启动一个Activity,涉及到的相关类大概有这些(AMS范围):
这里写图片描述

下面分析从Activity调用startActivity开始,直到新Activity进入onResume的流程。
(可以通过文章目录大致了解整个过程。)

ActivityManagerService

ActivityManagerService后面简称AMS,是用于应用管理和调度的系统服务。
在开机后,SystemServer会自动调用ActivityManagerService.setSystemProcess方法将AMS注册为系统服务:

//ActivityManagerService.java
public void setSystemProcess() {
    ...
    //Context.ACTIVITY_SERVICE = "activity" 
    ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
    ...
}

AMS继承自ActivityManagerNative,即为Binder的子类,并实现了IActivityManager接口。IActivityManager接口定义了给Client端调用的方法。

public final class ActivityManagerService extends ActivityManagerNative
        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback

ActivityManagerNative本身是单例模式的,因此系统中只会有一个ActivityManagerService实例。

public abstract class ActivityManagerNative extends Binder implements IActivityManager
{
    ...
    private static final Singleton<IActivityManager> gDefault = 
        new Singleton<IActivityManager>() {
        protected IActivityManager create() {
            IBinder b = ServiceManager.getService("activity");
            IActivityManager am = asInterface(b);

            return am;
        }
    };
    ...
}

ApplicationThread

每个应用(Application)都需要与系统打交道,最直接的就是跟ams打交道。因此,作为应用的主入口,ActivityThread实现了一个Binder内部类——ApplicationThread,用于和系统进程交互。

private class ApplicationThread extends ApplicationThreadNative 

ApplicationThreadNative继承自Binder,实现了IApplicationThread接口。IApplicationThread定义了许多与应用生命周期有关的方法。

public abstract class ApplicationThreadNative extends Binder
        implements IApplicationThread

分析Activity的启动流程

startActivity

在一个Activity要跳转到另外一个Activity时,常用的方法是调用startActivity方法,传入存有目标Activity信息的Intent,然后具体的操作会交给AMS来处理。
下面来看下从Activity到AMS期间的调用路径:

Activity.startActivity
Activity.startActivityForResult
Instrumentation.execStartActivity
ActivityManagerNative.getDefault().startActivity

直接来看Instrumentation.execStartActivity,此方法通过调用ActivityManagerNative.getDefault()获取AMS binder实例,然后调用AMS的startActivity方法,传入当前的IApplicationThread实例和Intent等内容:

//Instrumentation.java
public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) {
        IApplicationThread whoThread = (IApplicationThread) contextThread;
        ...
        try {
            ...
            int result = ActivityManagerNative.getDefault()
                .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;
    }

ActivityManagerNative.getDefault()方法通过ServiceManager.getService("activity")获取AMS Ibinder实例。

    //ActivityManagerNative.java
    static public IActivityManager getDefault() {
        return gDefault.get();
    }

    private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
        protected IActivityManager create() {
            IBinder b = ServiceManager.getService("activity");
            IActivityManager am = asInterface(b);
            return am;
        }
    };

ActivityManagerService.startActivity

流程进入AMS,接下来的部分调用栈如下:

ActivityManagerService.startActivity
ActivityManagerService.startActivityAsUser
ActivityStarter.startActivityMayWait
ActivityStarter.startActivityLocked
ActivityStarter.startActivityUnchecked
ActivityStackSupervisor.resumeFocusedStackTopActivityLocked
ActivityStack.resumeTopActivityUncheckedLocked
ActivityStack.resumeTopActivityInnerLocked

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

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

ActivityStack.resumeTopActivityInnerLocked判断如果当前有正在显示的Activity,则需要先停止,发起Pause流程。

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分别是ActivityRecord,ProcessRecord和IApplicationThread
                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并执行onCreateActivityStackSupervisor.realStartActivityLocked方法,当中的处理也会确保Application和相关类在Activity启动前就存在。

创建进程的调用栈:

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

ActivityManagerServiceProcess.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

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)

大致的流程已经列在目录中,就不再废话了。
整个流程看下来,可以发掘出进程,ActivityThread,Activity和AMS关系,大致如下:
这里写图片描述

这里只粗略地列出了一种启动Activity的流程,忽略的信息较多,启动模式和flag对任务栈的影响,甚至也没有提到任务栈,希望后面有时间再来分析总结。

AMS流程很多,代码架构也很庞大,要一下子读懂真的很困难,希望先将重要的流程各个击破,再反过来理解整个架构的思路。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值