MicroKibaco/CrazyDailyQuestion

2019-08-13: 说说你对app(或进程)启动流程的理解?

liyilin-jack opened this issue · 7 comments

2019-08-13: 说说你对app(或进程)启动流程的理解?

App 启动流程

  App启动流程 包括 bootloader , Kernel , init,zygotesystem_server.不过bootloader , Kernel 已经偏操作系统内核和驱动方面了,不做细讲,这里从init开始带大家深入理解App启动流程和顺序.

结构图

  • 借鉴 代码GG|陆晓明流程图

init

  init是Linux用户的第一个进程,进程号是1,说这个主要目的是引入我们话匣子zygote,init是如何创建zygote以及init属性服务是如何工作的呢?

  代码很复杂,我也看不懂,你只要知道是通过init.rc解析,然后执行各个阶段的动作,最后创建zygote就行了,当然还要处理socket属性服务方面的事情,因为涉及很多和Linux系统相关的知识.作为应用开发就没必要太关注这个了.

zygote

  当我上面没说,直接跳到zygote,zygote中文意思是受精卵,他是Android系统牵动Java世界的纽带.而system_server人如其名,系统中重要的server都会驻留在Java中.

  zygotesystem_server这两个进程分别是Java世界的半边天,任何进程的死亡,都会导致Java世界的Crash.

  zygote最初名字是android_process,这个名字是Android.mk文件被指定的,它本身就是个Native程序,和内核和驱动均无关.

  我们不需要深究太多,只要了解一点,Zygote觉的自己工作压力太大,于是通过startSystemServer分裂system_server作为Java的世界服务.zygote被命名为受精卵一点都不过分,如果支持中文编码其实更适合盘古_女娲

  

system_server

   ZygoteInt 调用 startSystemServer 创建 system_server,system_server 通过 hsp 方法完成自己的使命,并抛出异常,最终调用SystemServer 引入 main 方法,main 方法加载 libandroid_server.so 并调用 nativeinit1函数,init1函数通过JNI调用init2函数,init2函数创建一个线程,用于加载各种service,init1函数最终加入Binder通信系统

结构图

  • 借鉴 邓凡平 流程图

参考资源

1. 深入理解 Android
2. App系统启动流程分析
3. App 启动过程(含 Activity 启动过程) | 安卓 offer 收割基

App的启动方式:
冷启动:当启动应用时,后台没有该应用的进程。这是系统会创建一个新的进程分配给该应用。这是app的冷启动。冷启动因为系统会分配一个新的进程给app,此时的app会创建Applocation,然后才回去创建MainActivity,最后显示在界面上。

热启动:当启动应用的时候,后台已经存在该应用的进程了,(列:按back和home应用虽然会退出但是应用的进程仍然在后台运行,可以进入任务列表查看)这个是热启动,因为热启动不会创建进程。所以app不会创建Applocation,只会初始化MainActivity。一个应用从创建到销毁只会执行一次Applocation。

应用的启动步骤:

(1) Launcher通过Binder进程间通信机制通知ActivityManagerService,它要启动一个Activity

(2) ActivityManagerService通过Binder进程间通信机制通知Launcher进入Paused状态

(3) Launcher通过Binder进程间通信机制通知ActivityManagerService,它已经准备就绪进入Paused状态,于是ActivityManagerService就创建一个新的进程,用来启动一个ActivityThread实例,即将要启动的Activity就是在这个ActivityThread实例中运行

(4) ActivityThread通过Binder进程间通信机制将一个ApplicationThread类型的Binder对象传递给ActivityManagerService,以便以后ActivityManagerService能够通过这个Binder对象和它进行通信

(5) ActivityManagerService通过Binder进程间通信机制通知ActivityThread,现在一切准备就绪,它可以真正执行Activity的启动操作了

应用启动流程涉及到的类和对象:

(1) Launcher:Launcher本质上也是一个应用程序,和我们的App一样,也是继承自Activity,实现了点击、长按等回调接口,来接收用户的输入。

(2) ActivityManagerServices:简称AMS,服务端对象,负责系统中所有Activity的生命周期。

(3) ActivityThread:App的真正入口。当开启App之后,会调用main()开始运行,开启消息循环队列,这就是传说中的UI线程或者叫主线程。与ActivityManagerServices配合,一起完成Activity的管理工作

(4) ApplicationThread:用来实现ActivityManagerService与ActivityThread之间的交互。在ActivityManagerService需要管理相关Application中的Activity的生命周期时,通过ApplicationThread的代理对象与ActivityThread通讯。

(5) ApplicationThreadProxy:是ApplicationThread在服务器端的代理,负责和客户端的ApplicationThread通讯。AMS就是通过该代理与ActivityThread进行通信的。

(6) Instrumentation:每一个应用程序只有一个Instrumentation对象,每个Activity内都有一个对该对象的引用。Instrumentation可以理解为应用进程的管家,ActivityThread要创建或暂停某个Activity时,都需要通过Instrumentation来进行具体的操作。

(7) ActivityStack:Activity在AMS的栈管理,用来记录已经启动的Activity的先后关系,状态信息等。通过ActivityStack决定是否需要启动新的进程。

(8) ActivityRecord:ActivityStack的管理对象,每个Activity在AMS对应一个ActivityRecord,来记录Activity的状态以及其他的管理信息。其实就是服务器端的Activity对象的映像。

(9) TaskRecord:AMS抽象出来的一个“任务”的概念,是记录ActivityRecord的栈,一个“Task”包含若干个ActivityRecord。AMS用TaskRecord确保Activity启动和退出的顺序。

App启动白屏或黑屏的原因:是因为已进入到Activity,但是未加载到布局文件,就先显示来windows窗口的背景。黑屏/白屏就是显示的windows背景(这个就是theme的设置)

App启动白屏或黑屏解决方案:

(1) 为Theme设置背景图(会给人一种快速加载的感觉)

<stylename="Theme.AppStartLoad"parent="android:Theme">

<itemname="android:windowBackground">@drawable/ipod_bg

<itemname="android:windowNoTitle">true

</style>

(2) 为Theme设置透明属性(会给人较慢加载出来感觉)

<stylename="Theme.AppStartLoadTranslucent"parent="android:Theme">

<itemname="android:windowIsTranslucent">true

<itemname="android:windowNoTitle">true

</style>

App的启动优化:

(1) Application的创建过程中尽量少的进行耗时操作

(2) 如果用到SharePreference,尽量在异步线程中操作

(3) 减少布局的层次,并且生命周期回调的方法中尽量减少耗时的操作

APP启动在项目中碰到过黑白屏的问题

为什么我的 APP 启动会白屏或者黑屏

有时候我们会发现,我们在启动我们自己的 APP 的时候,总是有那么点时间是白屏(黑屏),经过了白屏(黑屏)后才会进入我们的 APP。那么这是为什么呢?

有很多的初始化放到了 Application 中去完成了,那么这个时候刚打开程序的时候就会有个耗时,就会出现白屏的效果。

所以这里程序加载有个顺序,当打开一个 Activity 的时候,并且这个 Activity 所属的 Application 还没有运行,系统会首先为这个 Activity 创建一个进程,创建进程的时候就会调用 Application 的 onCreate 方法。进程的创建和 onCreate 内部的初始化是需要时间的,如果这个时候过长,没有任何反应的话,那么对于用户来说是不不知道的,用户还以为自己没有点到呢,所以很显然是不可能在原页面等待加载的,那么这个时候就有了 StartingWindow(PerviewWindow)的出现,StartingWindow 出现在应用程序进程创建并且初始化完成之前,是个临时的窗口,对应的 WindowType是 TYPE_APPLICATION_STARTING 作用就是告诉用户,系统已经收到我们的操作了,正在对程序进行初始化,只要初始化完毕后就会移除这个窗口。

所以其实我们看到的白屏或者黑屏就是 StartingWindow,那么为什么是白色或者黑色呢?我们一般都会给我们的 Application 和 Activity 设置 Theme,系统就会根据我们所设置的 Theme 来决定 StartingWindow 的颜色。我们都知道 Window 布局的顶层是 DecorView,而 StaringWindow 显示的是一个空的 DecorView,只是这个 DecorView 会应用我们的这个 Activity 所指定的 Theme。我们默认的 Theme 是 @android:style/Theme.Light 的话,这个时候就会产生白屏了。黑屏就是应用了 @android:style/Theme.Black,好了到这里我们就彻底明白为什么会出现白屏或者黑屏了。

App启动白屏或黑屏解决方案:

(1) 为Theme设置背景图(会给人一种快速加载的感觉)

<stylename="Theme.AppStartLoad"parent="android:Theme">

<itemname="android:windowBackground">@drawable/ipod_bg

<itemname="android:windowNoTitle">true

</style> (2) 为Theme设置透明属性(会给人较慢加载出来感觉)

<stylename="Theme.AppStartLoadTranslucent"parent="android:Theme">

<itemname="android:windowIsTranslucent">true

<itemname="android:windowNoTitle">true

</style> App的启动优化:

(1) Application的创建过程中尽量少的进行耗时操作

(2) 如果用到SharePreference,尽量在异步线程中操作

(3) 减少布局的层次,并且生命周期回调的方法中尽量减少耗时的操作

app的启动流程分析:https://www.jianshu.com/p/28281b54d318

首先放上我参考的文章,感觉写的不错。Android - Activity 启动过程
我先说一下我理解的一个应用启动的大致流程。
第一步我们点击桌面上一个应用图标,这个时候管理者会向系统服务进程发送一个指令:我要打开一个activity;第二步既然要打开activity,总要有个新的进程装载吧,那么系统服务向最牛的进程,算是系统进程吧,发送创建A进程的请求,这个时候系统主进程会进行创建A进程的工作,先判断要创建的A进程是否存在,然后确定是否要创建A进程;第三步创建好A进程之后,A进程向系统服务进程说,我已经被创建好了,你可以给我发送我运行需要的东西了,然后系统服务进程就会向A进程发送指令,告诉A进程需要创建Applicationactivity等一系列操作。
上面一系列啰嗦的叙述,其中系统服务进程是system_server进程,最牛的系统主进程是Zygote进程,创建进程的操作是fock操作,判断进程的唯一性是查看ActivityManagerService中有没有A进程的ProcessRecord (可以理解为每个进程的uid+process)信息,创建A进程的同时在A进程中创建了ActivityThread;进程A中的ActivityThreadsystem_server进程的ActivityManagerService发送A进程创建好的指令,并把A进程中的ApplicationThread发给ActivityManagerService,然后system_server进程的ActivityManagerService通过ApplicationThreadProxy这个代理与进程中的ApplicationThread沟通,进一步在A进程中创建applicationactivity

这过程太复杂了,里边涉及了好多的点。只能大致的说一下,我再继续研究一下,有新的发现和想法再补充上来

  1. 点击图标后Launcher进程会通过Binder机制向AMS发起打开Activity的请求【IPC->Binder】
  2. AMS会通过ActivityStarter处理Intent和Flag(启动模式相关的内容),然后通过Socket通知zygote进程【IPC->Socket】
  3. zygote进程会进行孵化(虚拟机和资源的复制),然后fork出新进程
  4. 然后zygote进程会通过invokeDynamicMain()方法调用到ActivityThread的main方法【ActivityThread】
    public static void main(String[] args) {
        // 1. mainLooper
        Looper.prepareMainLooper();
        // 2. 创建ActivityThread,执行attach
        ActivityThread thread = new ActivityThread();
        thread.attach(false);
        // 3. Handler
        if (sMainThreadHandler == null) {
            sMainThreadHandler = thread.getHandler();
        }
        // 4. loop()
        Looper.loop();
    }
    
  5. main()中关于Handler相关的工作是:主线程Looper和Handler的创建、开启主线程Looper的消息循环
  6. main()另一工作就是创建ActivityThread对象,执行attach方法。【Application、ContentProvider】
    1. 先通过AMS执行bindApplication方法
    2. 内部会创建属于Application的ContextImpl对象,并且创建Application对象,建立两者的联系
    3. 创建ContentProvider,执行其onCreate()方法,并进行发布相关操作(前提是该app有ContentProvider)
    4. 执行Application的onCreate()方法

  • 进程间通信IPC的Binder机制有哪些应用的场景?
    • Binder 是基于 C/S 架构的
  • IPC中Socket方式有哪些应用场景?
    *
  • Application的Context上下文对象是在哪里初始化的?
    • ActivityThread---handleBindApplication()(初始化)
    • LoadedApk.makeApplication()
    • Instrumentation.newApplication(Class,Context)
      ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
    • Application.attach()
    • Application.attachBaseContext()
  • ContentProvider是在哪里创建、初始化和发布的?
    • ActivityManagerService---attachApplicationLocked()(创建)AppBindData
    • ApplicationThread---bindApplication()
    • ActivityThread---handleBindApplication()(初始化)
    • ActivityThread---installContentProviders()
    • ActivityThread---installProvider()
    • ActivityManagerService---publishContentProviders()(发布)
  • ContentProvider的onCreate()和Application的onCreate()方法哪个先执行?
    • ContentProvider的onCreate()

App 启动过程

一、整体了解

1、ActivityManagerService

简称 AMS,服务端对象,负责管理 Activity 生命周期。

2、ActivityThread

App 的入口,启动 App 后,会调用 ActivityThread.main(),开启 Looper、MessageQueue,与 ActivityManagerService 配合完成对 Activity 的管理。

3、ApplicationThread

实现 ActivityManagerService 与 ActivityThread 之间的交互,在 ActivityManagerService 需要管理 Application 中 Activity 的生命周期时,通过 ApplicationThread 代理对象和 ActivityThread 通信。

4、ApplicationThreadProxy

ApplicationThread 在服务端的代理对象,负责和客户端的 ApplicationThread 进行通信。

5、Instrumentation

每个应用程序只有一个 Instrumentation 对象,每个 Activity 内都有一个对该对象的引用,可以理解为应用进程的管家,ActivityThread 需要创建或者暂停某个 Activity 时,都需要通过 Instrumentation 进行操作。

6、ActivityStack

Activity 在 AMS 中的栈管理,用来记录已经启动的 Activity 的先后顺序、状态信息等,通过 ActivityStack 决定是否需要启动新的进程。

7、ActivityRecord

ActivityStack 管理的对象,每个 Activity 在 AMS 对应一个 ActivityRecord,用来记录 Activity 的状态以及其他管理信息,其实就是服务器端 Activity 对象的映射。

8、TaskRecord

AMS 抽象出来的一个任务的概念,是记录 ActivityRecord 的栈,一个 Task 包含若干个 ActivityRecord,AMS 通过 TaskRecord 确保 Activity 启动和退出的顺序。

二、Zygote

在 Linux 中,所有的进程都是由 init 进程直接或间接 fork 出来的,Zygote 进程也不例外。

手机开机后,Linux 内核加载完成后,会启动一个 init 进程。

每一个 App 其实都是:

  • 一个独立的 Dalvik 虚拟机
  • 一个独立的进程

所以,在系统中的第一个 Zygote 进程启动之后,再打开一个 App,其实就是开启一个新的进程。而为了实现资源共用和更快的启动速度,Android 系统开启新进程的方式是:通过 fork 第一个 Zygote 进程开启新进程,换句话说,其他应用所在的进程都是 Zygote 的子进程。

三、SystemServer

SystemServer 是一个进程,也是由 Zygote 进程 fork 出来的。

系统里比较重要的服务都是从这个进程里开启的,比如 ActivityManagerService、WindowManagerService、PackageManagerService 等。

Zygote 开启的时候会调用 ZygoteInit.main()

public static void main(String argv[]) {
    ZygoteServer zygoteServer = new ZygoteServer();

    // 标记 Zygote 开启
    ZygoteHooks.startZygoteNoThreadCreation();

    // Zygote 进入它自己的进程组
    try {
        Os.setpgid(0, 0);
    } catch (ErrnoException ex) {
        throw new RuntimeException("Failed to setpgid(0,0)", ex);
    }

    try {
        // 上报 Zygote 开启时间到分裂时间,除非重新启动
        if (!"1".equals(SystemProperties.get("sys.boot_completed"))) {
            MetricsLogger.histogram(null, "boot_zygote_init",
                    (int) SystemClock.elapsedRealtime());
        }

        String bootTimeTag = Process.is64Bit() ? "Zygote64Timing" : "Zygote32Timing";
        BootTimingsTraceLog bootTimingsTraceLog = new BootTimingsTraceLog(bootTimeTag,
                Trace.TRACE_TAG_DALVIK);
        bootTimingsTraceLog.traceBegin("ZygoteInit");
        RuntimeInit.enableDdms();
        
        // 开始 Zygote 初始化
        SamplingProfilerIntegration.start();

        boolean startSystemServer = false;
        String socketName = "zygote";
        String abiList = null;
        boolean enableLazyPreload = false;
        for (int i = 1; i < argv.length; i++) {
            if ("start-system-server".equals(argv[i])) {
                startSystemServer = true;
            } else if ("--enable-lazy-preload".equals(argv[i])) {
                enableLazyPreload = true;
            } else if (argv[i].startsWith(ABI_LIST_ARG)) {
                abiList = argv[i].substring(ABI_LIST_ARG.length());
            } else if (argv[i].startsWith(SOCKET_NAME_ARG)) {
                socketName = argv[i].substring(SOCKET_NAME_ARG.length());
            } else {
                throw new RuntimeException("Unknown command line argument: " + argv[i]);
            }
        }

        if (abiList == null) {
            throw new RuntimeException("No ABI list supplied.");
        }

        zygoteServer.registerServerSocket(socketName);
        // 在许多配置中, 避免急切的预加载资源和类文件
        // 在许多事例中, 在第一次 fork 时会预加载一些优先级高的事情
        if (!enableLazyPreload) {
            bootTimingsTraceLog.traceBegin("ZygotePreload");
            EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
                SystemClock.uptimeMillis());
            preload(bootTimingsTraceLog);
            EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
                SystemClock.uptimeMillis());
            bootTimingsTraceLog.traceEnd(); // ZygotePreload
        } else {
            Zygote.resetNicePriority();
        }

        // 完成 Zygote 的初始化
        SamplingProfilerIntegration.writeZygoteSnapshot();

        // 做一个 GC 初始化,在启动之后进行清理
        bootTimingsTraceLog.traceBegin("PostZygoteInitGC");
        gcAndFinalize();
        bootTimingsTraceLog.traceEnd(); // PostZygoteInitGC

        bootTimingsTraceLog.traceEnd(); // ZygoteInit
        
        // 禁止跟踪,以至于被 fork 的进程不能继承老的 Zygote
        Trace.setTracingEnabled(false);

        // Zygote 进程卸载根存储空间
        Zygote.nativeUnmountStorageOnInit();

        // 设置 seccomp 策略
        Seccomp.setPolicy();

        ZygoteHooks.stopZygoteNoThreadCreation();

        if (startSystemServer) {
            startSystemServer(abiList, socketName, zygoteServer);
        }

        Log.i(TAG, "Accepting command socket connections");
        zygoteServer.runSelectLoop(abiList);

        zygoteServer.closeServerSocket();
    } catch (Zygote.MethodAndArgsCaller caller) {
        caller.run();
    } catch (Throwable ex) {
        Log.e(TAG, "System zygote died with exception", ex);
        zygoteServer.closeServerSocket();
        throw ex;
    }
}

// 为 fork SystemServer 进程准备参数
private static boolean startSystemServer(String abiList, String socketName, ZygoteServer zygoteServer)
        throws Zygote.MethodAndArgsCaller, RuntimeException {
    long capabilities = posixCapabilitiesAsBits(
        OsConstants.CAP_IPC_LOCK,
        OsConstants.CAP_KILL,
        OsConstants.CAP_NET_ADMIN,
        OsConstants.CAP_NET_BIND_SERVICE,
        OsConstants.CAP_NET_BROADCAST,
        OsConstants.CAP_NET_RAW,
        OsConstants.CAP_SYS_MODULE,
        OsConstants.CAP_SYS_NICE,
        OsConstants.CAP_SYS_PTRACE,
        OsConstants.CAP_SYS_TIME,
        OsConstants.CAP_SYS_TTY_CONFIG,
        OsConstants.CAP_WAKE_ALARM
    );
    
    // 没有容量的容器运行,避免设置它
    if (!SystemProperties.getBoolean(PROPERTY_RUNNING_IN_CONTAINER, false)) {
        capabilities |= posixCapabilitiesAsBits(OsConstants.CAP_BLOCK_SUSPEND);
    }
    
    // 硬编码开启 system server
    String args[] = {
        "--setuid=1000",
        "--setgid=1000",
        "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,1032,3001,3002,3003,3006,3007,3009,3010",
        "--capabilities=" + capabilities + "," + capabilities,
        "--nice-name=system_server",
        "--runtime-args",
        "com.android.server.SystemServer",
    };
    ZygoteConnection.Arguments parsedArgs = null;

    int pid;

    try {
        parsedArgs = new ZygoteConnection.Arguments(args);
        ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
        ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);

        // 请求 fork system server 进程
        pid = Zygote.forkSystemServer(
                parsedArgs.uid, parsedArgs.gid,
                parsedArgs.gids,
                parsedArgs.debugFlags,
                null,
                parsedArgs.permittedCapabilities,
                parsedArgs.effectiveCapabilities);
    } catch (IllegalArgumentException ex) {
        throw new RuntimeException(ex);
    }

    /* For child process */
    if (pid == 0) {
        if (hasSecondZygote(abiList)) {
            waitForSecondaryZygote(socketName);
        }

        zygoteServer.closeServerSocket();
        handleSystemServerProcess(parsedArgs);
    }

    return true;
}

四、ActivityManagerService

简称 AMS,服务端对象,负责系统中所有 Activity 生命周期。

初始化时机:SystemServer 进程开启时。

public static void main(String[] args) {
    new SystemServer().run();
}

public SystemServer() {
    mFactoryTestMode = FactoryTest.getMode();
    
    mRuntimeRestart = "1".equals(SystemProperties.get("sys.boot_completed"));
}

private void run() {
    try {
        traceBeginAndSlog("InitBeforeStartServices");
        if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
            Slog.w(TAG, "System clock is before 1970; setting to 1970.");
            SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
        }

        String timezoneProperty =  SystemProperties.get("persist.sys.timezone");
        if (timezoneProperty == null || timezoneProperty.isEmpty()) {
            Slog.w(TAG, "Timezone not set; setting to GMT.");
            SystemProperties.set("persist.sys.timezone", "GMT");
        }

        if (!SystemProperties.get("persist.sys.language").isEmpty()) {
            final String languageTag = Locale.getDefault().toLanguageTag();

            SystemProperties.set("persist.sys.locale", languageTag);
            SystemProperties.set("persist.sys.language", "");
            SystemProperties.set("persist.sys.country", "");
            SystemProperties.set("persist.sys.localevar", "");
        }

        // system server 不能多线程调用
        Binder.setWarnOnBlocking(true);

        Slog.i(TAG, "Entered the Android system server!");
        int uptimeMillis = (int) SystemClock.elapsedRealtime();
        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN, uptimeMillis);
        if (!mRuntimeRestart) {
            MetricsLogger.histogram(null, "boot_system_server_init", uptimeMillis);
        }

        SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary());

        if (SamplingProfilerIntegration.isEnabled()) {
            SamplingProfilerIntegration.start();
            mProfilerSnapshotTimer = new Timer();
            mProfilerSnapshotTimer.schedule(new TimerTask() {
                    @Override
                    public void run() {
                        SamplingProfilerIntegration.writeSnapshot("system_server", null);
                    }
                }, SNAPSHOT_INTERVAL, SNAPSHOT_INTERVAL);
        }

        VMRuntime.getRuntime().clearGrowthLimit();

        // system server 会一直运行,所以它需要高效使用其内存
        VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);

        Build.ensureFingerprintProperty();

        // 在 system server 中, 在没有显式指定用户的情况下,访问环境路径是会报错的
        Environment.setUserRequired(true);

        // 在 system server 中, 应该对任何输入包进行解压缩,避免抛出 BadParcelableException
        BaseBundle.setShouldDefuse(true);

        // 确保 binder 进行系统调用时能运行在前台
        BinderInternal.disableBackgroundScheduling(true);

        // 增加 system_server 中 binder 线程的数量
        BinderInternal.setMaxThreads(sMaxBinderThreads);

        android.os.Process.setThreadPriority(
            android.os.Process.THREAD_PRIORITY_FOREGROUND);
        android.os.Process.setCanSelfBackground(false);
        Looper.prepareMainLooper();

        // 初始化 native services(本地服务库)
        System.loadLibrary("android_servers");

        // 检查上次我们尝试关闭是否失败
        performPendingShutdown();

        // 初始化 system context
        createSystemContext();

        // 创建 system service manager
        mSystemServiceManager = new SystemServiceManager(mSystemContext);
        mSystemServiceManager.setRuntimeRestarted(mRuntimeRestart);
        LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
        // 准备 thread pool 并行初始化 tasks
        SystemServerInitThreadPool.get();
    } finally {
        traceEnd();  // InitBeforeStartServices
    }

    // 开启服务
    try {
        traceBeginAndSlog("StartServices");
        startBootstrapServices();
        startCoreServices();
        startOtherServices();
        SystemServerInitThreadPool.shutdown();
    } catch (Throwable ex) {
        throw ex;
    } finally {
        traceEnd();
    }

    if (!mRuntimeRestart && !isFirstBootOrUpgrade()) {
        int uptimeMillis = (int) SystemClock.elapsedRealtime();
        MetricsLogger.histogram(null, "boot_system_server_ready", uptimeMillis);
        final int MAX_UPTIME_MILLIS = 60 * 1000;
        if (uptimeMillis > MAX_UPTIME_MILLIS) {
            Slog.wtf(SYSTEM_SERVER_TIMING_TAG,
                    "SystemServer init took too long. uptimeMillis=" + uptimeMillis);
        }
    }

    // 开启 Looper 循环
    Looper.loop();
    throw new RuntimeException("Main thread loop unexpectedly exited");
}

// 初始化上下文对象 mSystemContext
private void createSystemContext() {
    // 创建 ActivityThread 对象,ActivityThread.systemMain() 会调用 ActivityThread.attach(),在 attach 中创建了 Application 对象,并调用了 Application.onCreate()
    ActivityThread activityThread = ActivityThread.systemMain();
    // mSystemContext 实际上是一个 ContextImpl 对象
    mSystemContext = activityThread.getSystemContext();
    // 设置默认主题
    mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);

    final Context systemUiContext = activityThread.getSystemUiContext();
    systemUiContext.setTheme(DEFAULT_SYSTEM_THEME);
}

private void startBootstrapServices() {
    ...

    // 初始化 ActivityManagerService
    mActivityManagerService = mSystemServiceManager.startService(
            ActivityManagerService.Lifecycle.class).getService();
    mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
    mActivityManagerService.setInstaller(installer);

    // Power manager 需要被提前创建因为其他服务需要它
    mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);

    // 现在电源管理已经开始了,ActivityManagerService 负责电源管理功能
    // 初始化电源管理
    mActivityManagerService.initPowerManagement();

    // 初始化 DisplayManagerService,在 package manager 之前 需要提供 Display manager
    mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);

    // 开启 PackageManagerService
    mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
            mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
    
    ...
}

这是系统进程开启时的流程,在这之后,会开启系统的 Launcher 程序,完成系统界面的加载与显示。

五、Android 系统里面的服务器和客户端

服务器端:所有 App 共用的系统服务,比如 ActivityManagerService、PackageManagerService、WindowManagerService 等,当某个 App 要进行某项操作时,要告诉这些系统服务。

客户端:某个 App。

App A 调用 startActivity 不能直接打开 App B 的某个页面,而是通过一系列调用,告诉 AMS 要打开 App B 的某个页面,AMS 会通知 Zygote 进程 fork 一个新进程,来开启 App B。

App 与 AMS 之间通过 Binder 进行 IPC 通信,AMS 与 Zygote 之间通过 Socket 进行通信。

AMS 的用途:

  • 通知 Zygote 进程进行 fork 新进程
  • 管理系统中所有 Activity 生命周期

六、Launcher

Launcher 本身也是一个应用程序。

七、Instrumentation 和 ActivityThread

每个 Activity 都持有 Instrumentation 对象的一个引用,但整个进程只会存在一个 Instrumentation 对象。

当 startActivityForResult() 调用之后,实际上还是调用了 mInstrumentation.execStartActivity()。

这个类里面的方法大多数和 Application 和 Activity 有关,这个类就是完成对 Application 和 Activity 初始化和生命周期的工具类。

AMS -> ActivityThread -> Instrumentation

八、AMS 与 ActivityThread 之间的 Binder 通信

startActivity()
-> startActivityForResult()
-> Instrumentation.execStartActivity() -> checkStartActivityResult()
-> ActivityManager.getService().startActivity()
-> ActivityManagerService.startActivity() -> startActivityAsUser()
-> ActivityStarter.startActivityMayWait() -> startActivityLocked() -> startActivity() -> startActivityUnchecked() -> resumeTargetStackIfNeeded()
-> ActivityStackSupervisor.resumeFocusedStackTopActivityLocked()
-> ActivityStack.resumeTopActivityUncheckedLocked() -> resumeTopActivityInnerLocked()
-> ActivityStackSupervisor.startSpecificActivityLocked() -> realStartActivityLocked()
-> ActivityThread.ApplicationThread.scheduleLaunchActivity() -> sendMessage() -> handleLaunchActivity() -> performLaunchActivity()
-> Instrumentation.callActivityOnCreate() 
-> Activity.performCreate() -> onCreate()

ActivityManager.getService() 返回的就是 ActivityManagerService 的远程接口。

客户端:ActivityManagerProxy -> Binder驱动 -> ActivityManagerService:服务器

如果 AMS 想要通知 ActivityThread 做一些事情,还是通过 Binder 通信,不过是换成了 ApplicationThread 和 ApplicationThreadProxy。

ApplicationThreadProxy:服务器 -> Binder 驱动 -> 客户端:ApplicationThread

九、问答

1、一个 App 的程序入口到底是什么?

ActivityThread.main()。

2、整个 App 的主线程的消息循环是在哪里创建的?

是在 ActivityThread 初始化的时候,就已经创建消息循环了,所以在主线程里面创建 Handler 不需要指定 Looper,而如果在其他线程使用 Handler,则需要单独使用 Looper.prepare() 和 Looper.loop() 创建消息循环。

3、Application 是在什么时候创建的?onCreate()什么时候调用的?

也是在 ActivityThread.main() 的时候,再具体点,就是在 thread.attach(false) 的时候。

参考:APP启动过程