IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> Android实训(一):Android启动过程、Init进程、Zygote进程以及开机动画的修改 -> 正文阅读

[游戏开发]Android实训(一):Android启动过程、Init进程、Zygote进程以及开机动画的修改

Android开机启动

Android开机启动流程

  1. 手机开机后,引导芯片启动,从固化再ROM里执行预设代码,加载引导程序到RAM,bootLoader检查RAM,初始化参数
  2. 硬件参数初始化后,进入Kernel层,加载硬件设备驱动,初始化进程管理
  3. Kernel层加载完成后,硬件驱动与HAL层交互,进入到Native层,启动INIT进程
  4. 启动init进程也是android启动的第一个进程,init是贯穿整个linux的第一个进程,PID为1,之后启动adbd,logd等用户守护进程,并且启动serviceManager等服务,孵化出zygote进程,底层为C艹代码
  5. zygote进程由init进程解析init.rc文件后fork而成,加载虚拟机,孵化zygote的第一个进程SystemServer,它负责启动和管理整个Java Framework,包含了ActivityManager,WindowManager,PackageManager等九十多个服务
  6. zygote还负责启动APP进程,第一个进程为Launcher,所有的APP进程都由zygote fork而成

总的来说,就是通电后,先加载配置驱动,因为硬件品牌类型不同,不同品牌的驱动配置当然也不一样。再加载驱动,在开始启动系统

概述:Loader > Kernel > Native > Framework > Application

细分:BootRom > Bootloader > Kernel > Init > Zygote > SystemServer > Launcher

1. Android启动过程

Init->Zygote->SysetemServer->Launcher

init是第一个用户进程,它借助init.rc来启动各种服务,孵化zygote进程,启动SystemServer,启动Android服务,完成后启动Launcher

2. Init进程

adb shell ps查看所有进程,init进程的pid始终为1

代码位于system/core/init/main.cpp,通过main函数中的参数分别执行以下函数

  1. ueventd_main,负责设备节点文件工作,它通过两种凡是创建设备节点文件
  2. FirstStageMain,启动第一阶段
  3. SubcontextMain,初始化日志系统
  4. SetupSelinux,加载selinux规则,设置日志,Selinux是继承Linux的一套安全机制
  5. SecondStageMain,启动第二阶段

下面分别来说这些函数的内容

  • ueventd_main

    位于platform/system/core/init/ueventd.cpp

    通过两种方式创建设备节点文件分别为冷启动和热启动

    1. 冷启动只已经设定好的,统一创建好的文件节点例如cpu频率,分辨率,他们是不会变的
    2. 热启动为动态创建的节点例如usb插拔,充电状态节点等会变化,需要通过监听
  • FirstStageMain

    位于init/first_stage_init.cpp

    主要工作是挂载分区,创建设备节点和一些关键目录,初始化日志输出系统,传回参数给main函数,启用SELinux安全策略

  • SetupSelinux

    位于init/selinux.cpp

    初始化selinux,加载SELinux规则并启动,注册回调,设置需要写入kmsg的selinux日志,传入second_stage参数,回到mainf方法,启动第二阶段

  • SecondStageMain

    需要初始化属性系统,解析SELinux的匹配规则,处理子进程终止信号,启动系统属性服务,解析init.rc等文件。

    解析init.rc中,位于/init/init.cpp,入口函数为init SecondStageMain,通过传入给解析器解析,解析例如service、on、import对象,解析完后会按顺序将action加入到队列中,执行action执行函数,这是个while循环函数,解析放入队列这个操作可以称作第三节多,zygote就是这样启动的

总结就是:

第一阶段挂载分区,创建设备节点和关键目录,初始化日志输出系统,启动SELinux安全策略

第二阶段初始化系统属性,解析SELinux匹配规则,启动系统属性服务,落实第一阶段功能

第三阶段解析init.rc启动进程,无限循环,进行子进程事实监控

3. Zygote进程启动

在app_main.c中,main方法通过runtime.start启动虚拟机VM,注册JNI,通过反射机制调用ZygoteInit.java的main方法,注册Socket进行资源预加载,启动SystemServer来fork,同时也会循环来启动fork子进程

3.1 Zygote启动模式

32位和64位模式的不同导致ro.zygote只值也不同,现在混64位模式主流上是zygote64_32

zygote可以通过–参数来启动,如果是zygote启动模式,直接加载ZygoteInite;如果是application启动模式,则加载RuntimeInite;如果没有参数,则参数错误

runtime.start方法继承AndroidRunitme,没有实现方法它的start的方法,而父类的start方法主要用来开始虚拟机,注册JNI方法,通过JNI方法启动Zygote进程

3.2 ZygoteInit.main函数

位于frameworks\base\core\java\com\android\interna\os\ZygoteInit.java

  1. 调用preload()加载类和资源
  2. 调用ZygoteServer()创建两个Server端的Socket来等待ActivityManagerService来请求Zygote来创建新的引用程序进程
  3. 调用forkSystemServer启动SystemServer进程
  4. 调用runSelectLoop函数等待客户端请求,这个时候开启监听,这代表Zygote已经启动结束了,通过fork函数孵化app进程,通过反射的方式启动

3.3 资源的预加载-main函数中第一步

android系统的资源需要在启动前先进行加载和编译,不能到到需要用的时候在进行加载和编译,具体代码在preload方法中。例如一些系统的resource,一些class在frameworks/base/config/preloaded-classes中

3.4 线程方法-main函数中第三步

forkSystemServer方法会返回pid值,程序通过判断pid的值来进行操作,如果pid==0,表示当前为system_server子进程,当pid>0时,时进入父进程,即Zygote进程,此时,当Zygote进程启动完成后,最后在启动SystemServer进程

3.5 孵化应用进程-main函数中第四步

一般分为三层,第一层为APP层,即需要使用的应用进程;第二层为SystemServer系统服务层;第三层为Zygote层。

以Phone、SMS、Media等app层的应用进程为例,点击后

会进入SystemServer层的ActivityManagerService,接着会执行Process.Start()

通过socket到Zygote,Zygote拿到后,通过一系列操作,最后通过runSelectLoop方法返回一个PID,通过反射机制调用应用的入口函数main方法,最后启动应用

frameworks/base/core/java/com/android/internal/os/ZygoteServer.java

runSelectLoop通过创建一个ZygoteConnection对象,使用这个connection的processCommand方法,来启动应用进程

frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java

Zygote.forkAndSpecialize方法会调用native方法来fork app进程,fork成功后,子进程就得到了父进程的数据,pid==0是子进程执行,else是父进程执行,接着返回pid给client端,接着AMS就会继续执行。最终会执行handleChildProc方法

在handleChildProc方法中,如果!isZygote为false,返回ZygoteInit.childZygoteInit;否则返回ZygoteInit.zygoteInit

4. Android开机动画

init进程会启动Service Manager进程用来注册服务;也会启动zygote进程用来启动应用等;还有有一个surfaceflinger进程,该进程通过new SurfaceFilinger(),接着init(),执行startBootAnim()方法,接着启动bootanimation进程,该进程通过new对象一步步执行**onFirstRef(),readyToRun(),threadLoop(),movie()**方法,最后通过监听zygot进程子进程的systemServer进程中的开机进程,如果完成后就结束bootAnimation进程中的方法,启动Launcher

4.1 动画修改

bootanimation.zip一般存放system/memia文件下,一般都是原生的开机动画。通过

find ./ -name "bootanimation.zip"

来找到存放动画的目录

修改开机动画需要一部root属性,通过

adb pull bootanimation.zip

来pull原有动画,解压后会有一个desc.txt文件和很多part0、part1目录。desc文件内容如下

1080 2160 25
p 1 0 part0
p 0 0 part1

第一排分别对应分辨率像素宽度和高度,已经25代表帧数

第二排p代表标志位,1表示循环1次,0表示阶段间隔为0帧

第二排0表示无线循环

另外,desc.tx要在Linux文件生成,因为编码和空格不一样。part目录中的图片命名一定要是连续的。bootanimation文件一定要用zip打包

修改通过push命令

另外,鸿蒙没有找到memia文件夹

借同事的已root小米操作

5. adb查看开机动画文件

  • 插上手机,打开开发者选项

  • adb devices查看设备

  • 在这里插入图片描述

  • pull拉取文件

  • 查看文件

  • 在这里插入图片描述

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2022-05-07 11:27:07  更:2022-05-07 11:27:34 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 11:13:14-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码