Android启动流程(Java层)

简介: 写在前面的话目前打算是先把Android的启动流程包括luncher、Activity的启动以及Service启动,View的绘制,事件分发等进行分析,后面应该还会包括现阶段正在使用的框架MVVM的分析。

写在前面的话

目前打算是先把Android的启动流程包括luncher、Activity的启动以及Service启动,View的绘制,事件分发等进行分析,后面应该还会包括现阶段正在使用的框架MVVM的分析。可能是更新Android不会太久了,有点迷茫Android的未来到底在哪里,把握现在吧。
今天这部分讲解的是Android系统启动后加载各种服务的过程。

1 init

init是第一个进程,我们可以说它是root进程或者说有进程的父进程。init进程有两个责任,一是挂载目录,比如/sys、/dev、/proc,二是运行init.rc脚本。
init进程可以在/system/core/init找到。
init.rc文件可以在/system/core/rootdir/init.rc找到。
readme.txt可以在/system/core/init/readme.txt找到。
对于init.rc文件,Android中有特定的格式以及规则。在Android中,我们叫做Android初始化语言。


2 Zygote加载进程

Zygote本意是受精卵,Android中可以理解为孵化器。Android的应用的进程都是由Zygote孵化而来,因此他们都有共同的ppid(父进程的id)


3 SystemServer启动

Zygote启动完成后,Zygote创建新的进程去启动系统服务。我们都知道Android的进程间通信是通过binder机制,通过binder机制可以避免对某个服务的单独创建,所有的服务在系统启动后即创建完成。但是我们通过Context.getSystemService(String name)获的并不是我们的服务的代理类,我们获取的是各种Manager类。


3.1 SystemServer启动流程

打开SystemServer.java ,我们可以看到它是一个含有main方法的类,Zygote启动系统服务时会调用这个main方法。

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

main创建了SystemServer对象后,调用其run方法,下面是具体实现。

private void run() {
    try {
        Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "InitBeforeStartServices");
        //进行时间校验
        if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
            Slog.w(TAG, "System clock is before 1970; setting to 1970.");
            SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
        }
        //语言校验
        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", "");
        }
        
        ......
        //设置线程优先级
        android.os.Process.setThreadPriority(
            android.os.Process.THREAD_PRIORITY_FOREGROUND);
        android.os.Process.setCanSelfBackground(false);
        
        //开启了一个Looper用于消息处理,此处和ActivityThread创建消息队列循环一致
        Looper.prepareMainLooper();
        //加载了android_servers.so,里面应该是各个server
        System.loadLibrary("android_servers");
        performPendingShutdown();
        //创建了系统的上下文Context 3.1.1
        createSystemContext();
        //将SystemServiceManager放入LocalServices中
        mSystemServiceManager = new SystemServiceManager(mSystemContext);
        LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
    } finally {
        Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
    }

    try {
        Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartServices");
        //启动关键services 3.2
        startBootstrapServices();
        //启动核心services 3.3
        startCoreServices();
        //启动其他services 3.4
        startOtherServices();
    } catch (Throwable ex) {
        Slog.e("System", "******************************************");
        Slog.e("System", "************ Failure starting system services", ex);
        throw ex;
    } finally {
        Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
    }

    if (StrictMode.conditionallyEnableDebugLogging()) {
        Slog.i(TAG, "Enabled StrictMode for system server main thread.");
    }
    //开启消息队列循环
    Looper.loop();
    throw new RuntimeException("Main thread loop unexpectedly exited");
}

run()方法中先对时间和语言进行校验后,创建了一个消息队列,并通过createSystemContext()方法创建SystemServer的上下文对象,之后开始启动引导services,接下来是核心services以及最后启动其他services。


3.1.1 createSystemContext()过程

从名字中我们可以知道这个方法是用来创建系统的上下文对象,createSystemContext()中代码比较少,很容易理解。

private void createSystemContext() {
    //通过ActivityThread的systemMain()进行对象的创建 3.1.2
    ActivityThread activityThread = ActivityThread.systemMain();
    //将上下文对象赋值
    mSystemContext = activityThread.getSystemContext();
    mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);
}

3.1.2 Context创建的过程

ActivityThread创建的过程,不得不说谷歌的代码真是短小精悍啊。

public static ActivityThread systemMain() {
    if (!ActivityManager.isHighEndGfx()) {
        ThreadedRenderer.disable(true);
    } else {
        ThreadedRenderer.enableForegroundTrimming();
    }
    //好像注释都不需要了。
    ActivityThread thread = new ActivityThread();
    thread.attach(true);
    return thread;
}

接着我们来看thread.attach(true)方法。(参数我们传入的是true),这里只展示执行的代码。

private void attach(boolean system) {
    sCurrentActivityThread = this;
    mSystemThread = system;
    if (!system) {
       ......
    } else {
        // Don't set application object here -- if the system crashes,
        // we can't display an alert, we just want to die die die.
        //这句话挺有意思的。。。
        android.ddm.DdmHandleAppName.setAppName("system_process",
                UserHandle.myUserId());
        try {
            mInstrumentation = new Instrumentation();
            //创建context
            ContextImpl context = ContextImpl.createAppContext(
                    this, getSystemContext().mPackageInfo);
            mInitialApplication = context.mPackageInfo.makeApplication(true, null);
            //调用Application的onCreate()方法
            mInitialApplication.onCreate();
        } catch (Exception e) {
            throw new RuntimeException(
                    "Unable to instantiate Application():" + e.toString(), e);
        }
    }
    DropBox.setReporter(new DropBoxReporter());

    ViewRootImpl.addConfigCallback(new ComponentCallbacks2() {......});
}

//对象不重复创建
public ContextImpl getSystemContext() {
    synchronized (this) {
        if (mSystemContext == null) {
            //创建系统的上下文
            mSystemContext = ContextImpl.createSystemContext(this);
        }
        return mSystemContext;
    }
}

代码比较简单,通过createAppContext方法创建一个上下文对象,并通过makeApplication方法创建Application,并调用onCreate()方法,最后调用getSystemContext()将上下文赋值给mSystemContext。这边对上下文的创建就到这里结束了,下面开始对各种服务启动的流程分析。


3.2 startBootstrapServices()启动核心服务

启动核心服务的过程其实并没有多么的复杂,最开始被启动的是Installer,即系统安装apk时的一个服务类,启动完成Installer服务之后才能启动其他的系统服务,之后启动AMSPowerManagerServiceLightsServiceDisplayManagerService......,核心代码如下:

private void startBootstrapServices() {
    //系统安装apk时的一个服务类,启动完成Installer服务之后才能启动其他的系统服务
    //直接翻译了源码注释(有点无耻哈)。
    //等待installd完成启动,以便它有机会创建具有适当权限的关键目录,如/ data / user。 
    //在我们初始化其他服务之前,我们需要完成这个工作 startService 3.2.1
    Installer installer = mSystemServiceManager.startService(Installer.class);
    //启动ActivityManagerService
    mActivityManagerService = mSystemServiceManager.startService(
            ActivityManagerService.Lifecycle.class).getService();
    mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
    mActivityManagerService.setInstaller(installer);
    //电源管理器需要提前启动,因为其他服务需要它。
    //本地守护进程可能正在注册,因此它必须立即处理传入的绑定器调用(包括能够验证这些调用的权限)。
    mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);

    Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "InitPowerManagement");
    mActivityManagerService.initPowerManagement();
    Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
    //启动灯光service
    mSystemServiceManager.startService(LightsService.class);
    //启动显示service
    mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);
    //在初始化package manager完成前,我们需要默认显示
    mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);

    String cryptState = SystemProperties.get("vold.decrypt");
    if (ENCRYPTING_STATE.equals(cryptState)) {
        Slog.w(TAG, "Detected encryption in progress - only parsing core apps");
        mOnlyCore = true;
    } else if (ENCRYPTED_STATE.equals(cryptState)) {
        Slog.w(TAG, "Device encrypted - only parsing core apps");
        mOnlyCore = true;
    }

    traceBeginAndSlog("StartPackageManagerService");
    //PackageManagerService开始初始化
    mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
            mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
    mFirstBoot = mPackageManagerService.isFirstBoot();
    mPackageManager = mSystemContext.getPackageManager();
    Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
    
    if (!mOnlyCore) {
        boolean disableOtaDexopt = SystemProperties.getBoolean("config.disable_otadexopt",
                false);
        if (!disableOtaDexopt) {
            traceBeginAndSlog("StartOtaDexOptService");
            try {
                OtaDexoptService.main(mSystemContext, mPackageManagerService);
            } catch (Throwable e) {
                reportWtf("starting OtaDexOptService", e);
            } finally {
                Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
            }
        }
    }

    traceBeginAndSlog("StartUserManagerService");
    //多用户UserManagerService
    mSystemServiceManager.startService(UserManagerService.LifeCycle.class);
    
    Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
    
    AttributeCache.init(mSystemContext);
    //把几个service添加到ServiceManager的中
    mActivityManagerService.setSystemProcess();
    //启动传感器的服务,native方法
    startSensorService();
}

3.2.1 SystemServiceManager.startService的过程

启动service的过程比较简单,通过反射去创建service对象,其构造方法的参数为Context,并将其添加到SystemServiceManagermServices列表中。

/**
 * 通过反射去创建,其构造方法的参数为Context
 */
public <T extends SystemService> T startService(Class<T> serviceClass) {
    try {
        final String name = serviceClass.getName();
        // Create the service.
        if (!SystemService.class.isAssignableFrom(serviceClass)) {
            throw new RuntimeException("Failed to create " + name
                    + ": service must extend " + SystemService.class.getName());
        }
        final T service;
        try {
            Constructor<T> constructor = serviceClass.getConstructor(Context.class);
            service = constructor.newInstance(mContext);
        } catch (InstantiationException ex) {......}

        // 添加到mServices列表中
        mServices.add(service);
        try {
            //调用onStart方法
            service.onStart();
        } catch (RuntimeException ex) {......}
        return service;
    } finally {
        Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
    }
}

3.3启动核心服务

从代码中可以看出核心服务包括了管理电池相关的服务,收集用户使用每一个APP的频率、使用时常的服务以及WebView更新服务的启动。

private void startCoreServices() {
    //管理电池相关的服务
    mSystemServiceManager.startService(BatteryService.class);

    //收集用户使用每一个APP的频率、使用时常
    mSystemServiceManager.startService(UsageStatsService.class);
    mActivityManagerService.setUsageStatsManager(
            LocalServices.getService(UsageStatsManagerInternal.class));

    //WebView更新服务
    mWebViewUpdateService = mSystemServiceManager.startService(WebViewUpdateService.class);
}

3.4 启动其他服务

启动其他服务,包括蓝牙,摄像头相关服务,管理输入事件等服务,这里不赘述。

/**
 * 其他服务,包括蓝牙,摄像头相关服务,管理输入事件等服务,这里不赘述
 */
private void startOtherServices() {
    ......
    //划重点,这里会启动HomeActivity,下篇讲HomeActivity启动流程,这里mark下
    mActivityManagerService.systemReady(new Runnable() {
       @Override
        public void run() {
            ......
        }
    });
}

不过,里面有个重要的地方是关于HomeActivity的启动,调用了mActivityManagerService.systemReady(new Runnable()后,会启动HomeActivity,下篇讲解下。


写在后面的话

今天的分析好像并没有过多的流程,代码看起来也比较简单,后面的会比较复杂,我会将时序图上传,方便自己以后复习。

目录
相关文章
|
8月前
|
前端开发 Java API
2025 年 Java 全栈从环境搭建到项目上线实操全流程指南:Java 全栈最新实操指南(2025 版)
本指南涵盖2025年Java全栈开发核心技术,从JDK 21环境搭建、Spring Boot 3.3实战、React前端集成到Docker容器化部署,结合最新特性与实操流程,助力构建高效企业级应用。
2684 1
|
8月前
|
消息中间件 Java Kafka
Java 事件驱动架构设计实战与 Kafka 生态系统组件实操全流程指南
本指南详解Java事件驱动架构与Kafka生态实操,涵盖环境搭建、事件模型定义、生产者与消费者实现、事件测试及高级特性,助你快速构建高可扩展分布式系统。
404 7
|
8月前
|
消息中间件 Java 数据库
Java 基于 DDD 分层架构实战从基础到精通最新实操全流程指南
本文详解基于Java的领域驱动设计(DDD)分层架构实战,结合Spring Boot 3.x、Spring Data JPA 3.x等最新技术栈,通过电商订单系统案例展示如何构建清晰、可维护的微服务架构。内容涵盖项目结构设计、各层实现细节及关键技术点,助力开发者掌握DDD在复杂业务系统中的应用。
1631 0
|
10月前
|
自然语言处理 前端开发 Java
JBoltAI 框架完整实操案例 在 Java 生态中快速构建大模型应用全流程实战指南
本案例基于JBoltAI框架,展示如何快速构建Java生态中的大模型应用——智能客服系统。系统面向电商平台,具备自动回答常见问题、意图识别、多轮对话理解及复杂问题转接人工等功能。采用Spring Boot+JBoltAI架构,集成向量数据库与大模型(如文心一言或通义千问)。内容涵盖需求分析、环境搭建、代码实现(知识库管理、核心服务、REST API)、前端界面开发及部署测试全流程,助你高效掌握大模型应用开发。
947 5
|
8月前
|
Java 编译器
Java 17 Switch表达式:更简洁、更强大的流程控制
Java 17 Switch表达式:更简洁、更强大的流程控制
991 111
|
8月前
|
JavaScript Java 微服务
现代化 Java Web 在线商城项目技术方案与实战开发流程及核心功能实现详解
本项目基于Spring Boot 3与Vue 3构建现代化在线商城系统,采用微服务架构,整合Spring Cloud、Redis、MySQL等技术,涵盖用户认证、商品管理、购物车功能,并支持Docker容器化部署与Kubernetes编排。提供完整CI/CD流程,助力高效开发与扩展。
943 64
|
安全 Java 程序员
《从头开始学java,一天一个知识点》之:控制流程:if-else条件语句实战
**你是否也经历过这些崩溃瞬间?** - 看了三天教程,连`i++`和`++i`的区别都说不清 - 面试时被追问&quot;`a==b`和`equals()`的区别&quot;,大脑突然空白 - 写出的代码总是莫名报NPE,却不知道问题出在哪个运算符 这个系列为你打造Java「速效救心丸」!每天1分钟,地铁通勤、午休间隙即可完成学习。直击高频考点和实际开发中的「坑位」,拒绝冗长概念,每篇都有可运行的代码示例。明日预告:《for与while循环的使用场景》。 ---
291 19
|
8月前
|
JavaScript 安全 前端开发
Java开发:最新技术驱动的病人挂号系统实操指南与全流程操作技巧汇总
本文介绍基于Spring Boot 3.x、Vue 3等最新技术构建现代化病人挂号系统,涵盖技术选型、核心功能实现与部署方案,助力开发者快速搭建高效、安全的医疗挂号平台。
404 3
|
9月前
|
人工智能 Cloud Native Java
Java 技术栈企业级应用开发全流程
本指南通过构建企业级电商系统,全面解析现代化Java技术栈实战应用。涵盖Spring Boot 3、微服务架构、云原生部署、服务治理、监控可观测性及AI集成,助开发者掌握全流程开发技能,打造高效可扩展的企业级应用。
547 0
Java 技术栈企业级应用开发全流程
|
9月前
|
安全 Java 数据库
使用Java实现用户的注册和登录流程
以上提供了用户注册和登录的基本框架和必要的说明。在具体的应用场景中,可能还需结合框架特性如Spring Security等提供的高级特性来实现更为完备和安全的用户认证机制。在开发期间,务必注重代码的安全性、清晰性和可维护性,为用户资料保驾护航。
604 13