Android框架简介--启动过程--大体流程

Android设备的启动必须经历3个阶段,即Boot Loader,Linux Kernel和Android系统服务。严格来讲Android系统实际上是运行于Linux 内核上的一系列用户进程,并不算一个严格意义上的操作系统。一般面试问及启动流程都是从init进程开始


启动过程.png

重要的系统进程

第一个系统进程--init

init进程的pid值为0.通过解析init.rc脚本来构建出系统的初始运行形态,Android系统的native服务程序大多是在对应的rc脚本中描述并被相继启动。列举下几个由init进程启动的native进程

native 服务 代码位置 描述
MediaServer frameworks/av/media/mediaserver/main_mediaserver.cpp
frameworks/av/media/mediaserver/mediaserver.rc
mediaservice服务,mediaplayer的服务端
AudioServer frameworks/av/media/audioserver/main_audioserver.cpp
frameworks/av/media/audioserver/audioserver.rc
启动AudioFlinger和AudioPolicyService
SurfaceFlinger frameworks/native/services/surfaceflinger/main_surfaceflinger.cpp
frameworks/native/services/surfaceflinger/surfaceflinger.rc
显示系统
ServiceManager /frameworks/native/cmds/servicemanager/service_manager.c
/frameworks/native/cmds/servicemanager/servicemanager.rc
注册binder的服务

这些服务启动的方式都差不多,以surfaceflinger为例:

LOCAL_INIT_RC

在frameworks/native/services/surfaceflinger/Android.mk中有如下的变量

LOCAL_INIT_RC := surfaceflinger.rc

编译宏LOCAL_INIT_RC用于将服务相关的RC文件编译到相应位置。上面的Android.mk通过LOCAL_INIT_RC将对应的surfaceflinger.rc编译到/system/etc/init目录中

解析对应的rc文件

是在system\core\init\init.cpp里面的main函数解析这些rc文件

std::string bootscript = GetProperty("ro.boot.init_rc", "");
    if (bootscript.empty()) {
        parser.ParseConfig("/init.rc");
        parser.set_is_system_etc_init_loaded(
                parser.ParseConfig("/system/etc/init"));
        parser.set_is_vendor_etc_init_loaded(
                parser.ParseConfig("/vendor/etc/init"));
        parser.set_is_odm_etc_init_loaded(parser.ParseConfig("/odm/etc/init"));
    } else {
        parser.ParseConfig(bootscript);
        parser.set_is_system_etc_init_loaded(true);
        parser.set_is_vendor_etc_init_loaded(true);
        parser.set_is_odm_etc_init_loaded(true);
    }

service执行

init进程解析init.rc后,会将相应的action 放到队列中,之后会按action在action_queue这个队列中的顺序去执行操作

我们先看下surfaceflinger.rc的定义

service surfaceflinger /system/bin/surfaceflinger
    class core animation
    user system
    group graphics drmrpc readproc
    onrestart restart zygote

surfaceflinger属于class core
调用class_start命令的地方在init.rc中,当执行boot action的时候,顺序执行就能执行到这个命令,首先启动的core一级别的服务

on boot
    # Start standard binderized HAL daemons
    class_start hal

    class_start core

on nonencrypted
    class_start main
    class_start late_start

init进程最后会通过fork的方式去启动服务

孵化进程 -- Zygote

Android中大多数应用进程和系统进程都是通过Zygote进程来生成。Zygote为孵化的应用程序提供了几个基础资源:常用类,JNI函数,主题资源,共享库

Zygote主要做两件事:孵化应用进程,启动SystemServer.

Zygote启动后的大体流程如下:

Zygote启动.png

Zygote启动过程分为native世界和java世界
native层的入口在
frameworks/base/cmds/app_process/app_main.cpp
java层的入口在
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

native层主要就是创建虚拟机,之后进入java世界,java层主要做四件事:注册socket,预加载资源,启动System Server,进入Loop循环。最后就是在loop循环中监听SystemServer的socket连接。

Android的“系统服务” -- SystemServer

SystemServer提供了众多的用java语言编写的系统服务,像AMS,PMS,以及WMS等都只是运行在system_server这个进程中的线程
SystemServer的路径在
frameworks/base/services/java/com/android/server/SystemServer.java
入口就是main函数

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

java的服务可以分成三类:

  • BootstrapServices
    Installer, AMS, Power Manager,Display Manager,PMS等
  • CoreServices
    DropBoxManagerService, BatteryService, UsageStatsService,WebViewUpdateService
  • OtherServices
    这类数量最多,包括一些我们经常接触的如WMS,InputManagerService

SystemServer启动的服务很多,服务间也会有相互依赖的情况,为了解决依赖的时序问题,SystemServer主要通过分批启动和分阶段启动来处理。

主要利用了SystemServiceManager的startBootPhase(),
下面的图片拷贝自http://gityuan.com/2016/02/20/android-system-server-2/

system_server_boot_process.jpg

这些启动阶段会穿插在各项的服务启动序列中。 startBootPhase会去回调用service的onBootPhase方法,对应的servcie才会去执行对应的操作

 public void startBootPhase(final int phase) {
        if (phase <= mCurrentPhase) {
            throw new IllegalArgumentException("Next phase must be larger than previous");
        }
        mCurrentPhase = phase;

        Slog.i(TAG, "Starting phase " + mCurrentPhase);

                    service.onBootPhase(mCurrentPhase);

启动Launcher

在PHASE_SYSTEM_SERVICES_READY 之后,SystemServer会调用AMS的systemReady的方法, 改方法中就回去执行startactivity的流程

//phase480 && 500
      mSystemServiceManager.startBootPhase(SystemService.PHASE_LOCK_SETTINGS_READY);
      mSystemServiceManager.startBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY);
      
      ...
      mActivityManagerService.systemReady(() -> {

             //phase550
             mSystemServiceManager.startBootPhase(
                     SystemService.PHASE_ACTIVITY_MANAGER_READY);
             ...
             //phase600
             mSystemServiceManager.startBootPhase(
                     SystemService.PHASE_THIRD_PARTY_APPS_CAN_START);
          }
      }
    }
 public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
        traceLog.traceBegin("PhaseActivityManagerReady");
        synchronized(this) {
            if (mSystemReady) {
                // If we're done calling all the receivers, run the next "boot phase" passed in
                // by the SystemServer
                if (goingCallback != null) {
                    goingCallback.run();
                }
                return;
            }

           startHomeActivityLocked(currentUserId, "systemReady");

}

AMS的systemReady会先执行参数Runnable,主要执行几个servcie的systemRunning方法,之后会去启动Launcher,Launcher启动后,会回调AMS的activityIdle, 最终会调用到AMS的finishBooting(),进入阶段Phase1000。

推荐阅读更多精彩内容