Activity启动过程

概述

Activty是四大组件之首,重要性不言而喻。这篇笔记整理于寒假实习期间,大致总结Activity的启动流程,由于整个启动过程实在太绕,调用链太长,暂时没有完整分析一遍,空缺的看需要再补充。分析过程以API-26为基础。

几个基础对象

  • ActivityManagerService:简称AMS,服务端对象,负责系统中的所有Activity的生命周期。
  • ActivityThread:App的真正入口。当开启App之后,会调用main()开始执行,开启消息循环队列,这就是传说中的UI线程或者说主线程。与AMS配合一起完成Activity的管理。
  • ApplicationThread:用来实现AMS与ActivityThread之间的交互。在AMS需要管理相关Application中的Activity的生命周期的时候,通过Application Thread的代理对象与Activity Thread通讯。
  • ApplicationThreadProxy:是ApplicationThread在服务器端的代理,负责和客户端的ApplicationThread通讯。AMS就是通过该代理和ActivityThread通讯的。
  • Instrumentation:每个应用程序只有一个Instrumentation对象,每个Activity内都有一个对该对象的引用。Instrumentation可以理解为应用进程的管家,ActivityThread要创建或暂停某个Activity时,都需要通过Instrumentation来进行具体的操作。
  • Activity Stack:Activity在AMS的栈管理,用来记录已经启动的Activity的先后关系、状态信息等。
  • ActivityRecord:ActivityStack的管理对象,每个Activity在AMS对应一个ActivityRecord,用来记录Activity的状态及其他管理信息。其实就是服务端的Activity对象的映像。
  • TaskRecord:AMS抽象出来的一个“任务”的概念。是记录ActivityRecord的栈。一个Task包含若干个ActivityRecord。AMS用TaskRecord确保Activity启动和退出的顺序。

http://duanqz.github.io/2016-02-01-Activity-Maintenance#activityrecord

ActivityRecord:

ActivityRecord是AMS调度Activity的基本单位。它需要记录AndroidManifest.xml中定义的Activity的静态特征。同时也需要记录Activity在被调度时的变化。其内部的属性比较多:
Activity启动过程_第1张图片
每次启动一个新的Activity时都会创建一个ActivityRecord对象。

TaskRecord:

TaskRecord的职责是管理多个ActivityRecord。所谓的任务、任务栈指的就是TaskRecord。启动Activity时需要找到Activity的宿主任务,如果不存在,则需要创建一个,也就是说所有的ActivityRecord都必须有宿主。TaskRecord与ActivityRecord是一对多的关系。TaskRecord中包含了ActivityRecord的数组。同时TaskRecord还需要维护任务栈本身的状态。其内部的属性如下:
Activity启动过程_第2张图片
在TaskRecord中提供了一系列方法用于管理任务栈:
Activity启动过程_第3张图片

ActivityStack:

从名字上看感觉它才是真正的栈,实际上它是一个manager的角色,负责管理协调ActivityRecord和TaskRecord。

总结就是,ActivityRecord是对应每个Activity,TaskRecord是对应每个任务栈,ActivityStack是用于管理协调ActivityRecord和TaskRecord的角色

Activity启动过程_第4张图片


Activity启动过程

调用startActivity方法,最终都会调用startActivityForResult方法。在startActivityForResult方法内部,又会调用Instrumentation中的execStartActivity方法。而在execStartActivity内部,又会通过ActivityManagerNative来实现。ActivityManagerNative继承自Binder,实现了IActivityManager接口,是一个抽象类。ActivityManagerNative的实现类是AMS。
ActivityManagerNative中的getDefault:

    /**
     * Retrieve the system's default/global activity manager.
     */
    static public IActivityManager getDefault() {
        return gDefault.get();
    }
    private static final Singleton gDefault = new Singleton() {
        protected IActivityManager create() {
            IBinder b = ServiceManager.getService("activity");
            if (false) {
                Log.v("ActivityManager", "default service binder = " + b);
            }
            IActivityManager am = asInterface(b);
            if (false) {
                Log.v("ActivityManager", "default service = " + am);
            }
            return am;
        }
    };

Singleton是一个封装的单例,这里通过单例对外提供ActivityMangerNative的实例。在第一次调用时,会通过ServiceManager.getService方法拿到AMS的代理对象。

在拿到AMS的代理对象后,就可以调用它的startActivity方法来启动Activity,而在AMS的startActivity内部,会调用startActivityAsUser方法:

    @Override
    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) {
        enforceNotIsolatedCaller("startActivity");
        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
        // TODO: Switch to user app stacks here.
        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
                profilerInfo, null, null, bOptions, false, userId, null, null);
    }

从startActivityAsUser方法可以看出,启动过程又转移到了ActivtyStarter的startActivityMayWait方法中继续进行(在《Android开发艺术探索》中说是ActivityStackSupervisor,可能是SDK版本不同)。ActivityStarter类是负责处理Activity的Intent和Flags的逻辑,还有管理Stack和TaskRecord的。。在这个方法内部会调用ActivityStack的topRunningActivitiesLocked方法,。

启动流程太长了,写不下去了,下次有精力再继续。根据Activity的生命周期大致可以猜测,会判断Activity的启动模式与FLAG,决定是否需要创建ActivityRecord与TaskRecord,然后将之前的Activity暂停,再回调新的Activity的onCreate方法。

18.01.25补,大致流程图如下:
Activity启动过程_第5张图片

流程图有几点解释:
1. ActivityStarter:

/**
 * 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.
 */
 ```
 从官方注释可以知道ActivityStarter主要解释了怎样启动一个Activity。这里说的“how”,包括设置ActivityRecord、TaskRecord等信息。

 2. ActivityStackSupervisor:主要用于管理ActivityStack中的信息。
 3. ActivityStack:要注意的ActivityStack并不是任务栈,任务栈的真正实现是TaskRecord,ActivityStack是管理协调管理TaskRecord、ActivityRecord的类。
 4. ActivityStarter:
     * startActivityMayWait:根据Intent获取到Activity的启动信息(ResolveInfo和ActivtyInfo),获取到调用者的PID和UID。
     * startActivityLocked:创建ActivityRecod,含有Activity的核心信息。
     * startActivityUnchecked:根据启动的FLAG信息,设置TaskRecord。
 5. 核心是ActivityStack#resumeTopActivityInnerLocked方法:根据ActivityRecord和ActivityOptions完成Activity的切换,移至栈顶。
 6. ActivityStackSupervisor#realStartActivityLocked方法:含有启动的核心方法scheduleLaunchActivity,即调用IApplicationThread的scheduleLaunchActivity方法。

-----
在启动完Activity之后,回到Instrucmentation中的execStartActivity里,接着会执行checkStartActivityResult方法:
```java
    /** @hide */
    public static void checkStartActivityResult(int res, Object intent) {
        if (res >= ActivityManager.START_SUCCESS) {
            return;
        }

        switch (res) {
            case ActivityManager.START_INTENT_NOT_RESOLVED:
            case ActivityManager.START_CLASS_NOT_FOUND:
                if (intent instanceof Intent && ((Intent)intent).getComponent() != null)
                    throw new ActivityNotFoundException(
                            "Unable to find explicit activity class "
                            + ((Intent)intent).getComponent().toShortString()
                            + "; have you declared this activity in your AndroidManifest.xml?");
                throw new ActivityNotFoundException(
                        "No Activity found to handle " + intent);
            case ActivityManager.START_PERMISSION_DENIED:
                throw new SecurityException("Not allowed to start activity "
                        + intent);
            case ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT:
                throw new AndroidRuntimeException(
                        "FORWARD_RESULT_FLAG used while also requesting a result");
            case ActivityManager.START_NOT_ACTIVITY:
                throw new IllegalArgumentException(
                        "PendingIntent is not an activity");
            case ActivityManager.START_NOT_VOICE_COMPATIBLE:
                throw new SecurityException(
                        "Starting under voice control not allowed for: " + intent);
            case ActivityManager.START_VOICE_NOT_ACTIVE_SESSION:
                throw new IllegalStateException(
                        "Session calling startVoiceActivity does not match active session");
            case ActivityManager.START_VOICE_HIDDEN_SESSION:
                throw new IllegalStateException(
                        "Cannot start voice activity on a hidden session");
            case ActivityManager.START_CANCELED:
                throw new AndroidRuntimeException("Activity could not be started for "
                        + intent);
            default:
                throw new AndroidRuntimeException("Unknown error code "
                        + res + " when starting " + intent);
        }
    }

在这方法内部,通过启动的结果,判断是否正常启动,如果没有正常启动,抛出相应的异常。


双方跨进程通信

  1. 在client端,是通过ActivityManager来获取到AMS的单例对象,是一个AMS的代理对象,在之前的版本中对应的是ActivityManagerProxy(ActivityManagerNative内部类)。
  2. 在AMS进程中,是通过client端传过来的IApplicationThread对象(ApplicationThread)的代理对象(通过attachApplication(IApplication thread)方法),来实现与client端通信的。

如下图:
Activity启动过程_第6张图片


零散知识点

  • App与AMS通过Binder进行IPC,而AMS(SystemServer进程)与Zygote通过Socket进行IPC。
  • 在Android系统中,任何一个Activity的启动都是由AMS和应用程序进程(主要是ActivityThread)相互配合来完成的。AMS服务统一调度系统中所有进程的Activity启动,而每个Activity的启动过程则由其所属的进程具体完成。

总结

关于Activity的启动过程还有很多点可以深入,比如AMS进程与App进程通信的具体过程、在ActivityStackSupervisor、ActivityStack中到底是怎样处理Activity信息的等等,还很多要学的。

https://juejin.im/entry/57a06455a633bd00601394e0
http://blog.csdn.net/zhaokaiqiang1992/article/details/49428287#%E5%89%8D%E8%A8%80
http://blog.csdn.net/singwhatiwanna/article/details/18154335

http://dev.dafan.info/detail/252012?p= 探索7.x, 全面解析Activity启动框架 (1)
http://www.heqiangfly.com/2016/04/08/android-source-code-analysis-ams-app-ipc/ Android AMS 与 APP 进程通信
http://www.heqiangfly.com/2016/04/10/android-source-code-analysis-activity-start-process/ Android startActivity 流程分析

你可能感兴趣的:(android)