前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android框架简介--启动过程--大体流程

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

作者头像
小蚂蚁与大象
发布2022-04-02 08:03:54
7000
发布2022-04-02 08:03:54
举报

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中有如下的变量

代码语言:javascript
复制
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文件

代码语言:javascript
复制
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的定义

代码语言:javascript
复制
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一级别的服务

代码语言:javascript
复制
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函数

代码语言:javascript
复制
    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才会去执行对应的操作

代码语言:javascript
复制
 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的流程

代码语言:javascript
复制
//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);
          }
      }
    }
代码语言:javascript
复制
 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。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2022.03.25 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 重要的系统进程
    • 第一个系统进程--init
      • LOCAL_INIT_RC
      • 解析对应的rc文件
      • service执行
    • 孵化进程 -- Zygote
      • Android的“系统服务” -- SystemServer
        • 启动Launcher
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档