Android 基础技术——Framework

笔者希望做一个系列,整理 Android 基础技术,本章是关于 Framework

简述 Android 系统启动流程

当按电源键触发开机,首先会从 ROM 中预定义的地方加载引导程序 BootLoader 到 RAM 中,并执行 BootLoader 程序启动 Linux Kernel, 然后启动用户级别的第一个进程: init 进程(汇编调用)。init 进程会解析 init.rc 脚本做一些初始化工作,包括挂载文件系统、创建工作目录以及启动系统服务进程等,其中系统服务进程包括 Zygote、service manager、media 等(C++层的)。在 Zygote 中会进一步去启动 system_server进程(JAVA 层),然后在 system_server 进程中会启动 AMS、WMS、PMS 等服务,等这些服务启动之后,AMS 中就会打开 Launcher 应用的 home Activity,最终就看到了手机的 "桌面"。

Android 系统中有多少种不同的进程
  • init进程  :用户态的第一个进程解析init.rc创建各自服务进程(media, 守护进程),其中有一个叫zygote进程
  • zygote进程 : 一个进程所需要的必要资源 preloadclass, 虚拟机vm
  • system_server进程: 从zygote进程fork ,创建大量的服务(AMS,PMS,WMS等),加载Android framework所需要的资源context。
  • app进程:从zygote进程fork

init 进程是什么,作用是什么

init进程是Linux系统中用户空间的第一个进程,进程号固定为1, 是C++进程. 由kernel启动

Kernel启动后,在用户空间启动init进程,并调用init中的main()方法执行init进程的职责。

1. 创建mkdir和挂载mount启动所需要的文件目录 

  1. 初始化和启动属性服务 
  2. 解析init.rc配置文件并启动Zygote进程,是由init进程fork出来的

zygote进程是什么,作用是什么

Zgyote 是Android中的第一个art虚拟机 Android Runtime,他通过socket的方式与其他进程进行通信。

作用1 zygote fork的第一个java进程 SystemServer 进程

SystemServer 会开启一系列服务:AMS, WMS, PMS, PKMS等等

作用2从zygote fork子进程app Launcher进程

Launcher->app>fork  

app_main.cpp做了什么,或者另外一种说法:Zygote是如何被启动的?

创建zygote进程,走到app_main.cpp的main方法,它是zygote进程的入口

app_main.cpp的main方法流程如下:

  • 首先是Native层 startVm 启动了虚拟机!!! 这里就是启动JAVA虚拟机
  • 然后 调用startReg函数为java虚拟机注册JNI方法
  • 通过jni调用走到ZygoteInit.main,ZygoteInit.main() 是java层方法
    • registerZygoteSocket() 注册一个Socket Server接收AMS请求,socketName以ANDROID_SOCKET_开头;
    • preload(),预加载资源,例如常用类、颜色、drawable、JNI函数;以预加载类为例,读取/system/etc/preloaded-classes文件中配置的类名,通过Class.forName反射加载,常用类Activity、intent、String、Integer、TextView、Button
    • startSystemServer() ,内部通过Zygote.forkSystemServer启动SystemServer
    • runSelectLoop() 循环等待处理请求
system_server 为什么要在 Zygote 中启动,而不是由 init 直接启动呢

Zygote 作为一个孵化器,可以提前加载一些资源,这样 fork() 时基于 Copy-On-Write 机制创建的其他进程就能直接使用这些资源,而不用重新加载。比如 system_server 就可以直接使用 Zygote 中的 JNI 函数、共享库、常用的类、以及主题资源

使用 Zygote 进程去孵化应用进程有什么好处为什么不是让 system_server 去孵化? 

好处:应用在启动的时候需要做很多准备工作,包括启动虚拟机,加载各类系统资源等等,这些都是非常耗时的,如果能在zygote里就给这些必要的初始化工作做好,子进程在fork的时候就能直接共享,那么这样的话效率就会非常高。

为什么不是 system_server 进行 fork:

  • 首先 system_server 相比 Zygote 多运行了 AMS、WMS、PMS 等服务,这些对一个应用程序来说是不需要的。
  • 另外进程的 fork() 对多线程不友好,仅会将发起调用的线程拷贝到子进程,这可能会导致死锁,而 system_server 中肯定是有很多线程的。 

Zygote 为什么不采用 Binder 机制进行 IPC 通信? 
  • 第一个原因,我们可以设想一下采用binder调用的话该怎么做,首先zygote要启用binder机制,需要打开binder驱动,获得一个描述符,再通过mmap进行内存映射,还要注册binder线程,这还不够,还要创建一个binder对象注册到serviceManager,另外AMS要向zygote发起创建应用进程请求的话,要先从serviceManager查询zygote的binder对象,然后再发起binder调用,这来来回回好几趟非常繁琐,相比之下,zygote和SystemServer进程本来就是父子关系,对于简单的消息通信,用管道或者socket非常方便省事。
  • 第二个原因,如果zygote启用binder机制,再fork出SystemServer,那么SystemServer就会继承了zygote的描述符以及映射的内存,这两个进程在binder驱动层就会共用一套数据结构,这显然是不行的,所以还得先给原来的旧的描述符关掉,再重新启用一遍binder机制,这个就是自找麻烦了。
  • 第三个原因:Binder 机制中存在 Binder 线程池,是多线程的,如果 Zygote 采用 Binder 的话就存在上面说的 fork() 与 多线程的问题了。其实严格来说,Binder 机制不一定要多线程,所谓的 Binder 线程只不过是在循环读取 Binder 驱动的消息而已,只注册一个 Binder 线程也是可以工作的,比如 service manager 就是这样的。实际上 Zygote 尽管没有采取 Binder 机制,它也不是单线程的,但它在 fork() 前主动停止 了其他线程,fork() 后重新启动了
多线程进程的fork调用会有什么问题?

会发生死锁

在POSIX 标准中,fork 的行为是这样的:复制整个用户空间的数据(通常使用 copy-on-write 的策略, 所以可以实现的速度很快)以及所有系统对象,然后仅复制当前线程到子进程。这里:所有父进程中别的线程,到了子进程中都是突然蒸发掉的

假设这么一个环境,在 fork 之前,有一个子线程 lock 了某个锁,获得了对锁的所有权。fork 以 后,在子进程中,所有的额外线程都人间蒸发了。而锁却被正常复制了,在子进程看来,这个锁没有主人,所以没有任何人可以对它解锁。当子进程想 lock 这个锁时,不再有任何手段可以解开 了。程序发生死锁。

SystemServiceManager和service_manager的区别
  • SystemServiceManager 专门管理各种服务的启动  java层的各种服务:AMS, PMS, WMS。SystemServiceManager 的ArrayList<SystemService> mServices 添加上面的服务
  • service_manager 是C++层的 它是0号 binder服务

如果我们启动一个hello World安卓用于程序,里面不另外启动其他线程,这个里面最少要启动多少个线程

启动4个 线程 

  • main线程,只是程序的主线程,也是日常用到的最多的线程,也叫UI线程,因为android的组件是非线程安全的,所以只允许UI/MAIN线程来操作。 
  • GC线程,java有垃圾回收机制,每个java程序都有一个专门负责垃圾回收的线程
  • Binder1 就是我们的ApplicationThread,这个类实现了Ibinder接口,用于进程之间通信,具体来说,就是我们程序和AMS通信的工具 
  • Binder2 就是我们的ViewRoot.W对象,它也是实现了IBinder接口,就是用于我们的应用程序和 wms通信的工具。 wms就是WindowManagerServicer ,和ams差不多的概念,不过它是管理窗口的系统服务。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/398446.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

见微知著:数据可视化助力数字化时代决策智慧

在数字化时代的浪潮中&#xff0c;数据可视化显然是推动数字化进程不可或缺的利器。通过将复杂的数据转化为直观的图形和图表&#xff0c;数据可视化为企业和组织提供了更清晰、更有效的方式来理解和应用大量的数字信息。下面我就以可视化从业者的角度&#xff0c;来简单聊聊这…

Spring Boot项目怎么对System.setProperty(key, value)设置的属性进行读取加解密

一、前言 之前我写过一篇文章使用SM4国密加密算法对Spring Boot项目数据库连接信息以及yaml文件配置属性进行加密配置&#xff08;读取时自动解密&#xff09;&#xff0c;对Spring Boot项目的属性读取时进行加解密&#xff0c;但是没有说明对System.setProperty(key, value)设…

高性能三防平板有哪几款推荐的|亿道三防onerugged

我非常荣幸地向大家推荐几款高性能的三防平板电脑&#xff0c;这些产品都来自亿道三防onerugged系列。它们以其卓越的性能和出色的工艺设计&#xff0c;成为行业中备受瞩目的产品。 首先&#xff0c;让我们关注这些高性能三防平板所搭载的处理器。这些产品采用了基于Intel Cor…

opencv之cvScalar

CV_INLINE CvScalar cvScalar( double val0, double val1 CV_DEFAULT(0), double val2 CV_DEFAULT(0), double val3 CV_DEFAULT(0)) { CvScalar scalar; scalar.val[0] val0; scalar.val[1] val1; scalar.val[2] val2; scalar.val[3] val3; return scalar; } 该函数的…

【ArcGIS微课1000例】0104:二位面状数据转三维多面体(建筑物按高度拉伸)

文章目录 一、加载数据二、添加高度字段三、三维拉伸显示四、生成三维体数据五、注意事项一、加载数据 打开ArcScene,加载配套实验数据(0104.rar中的二维建筑物矢量数据,订阅专栏,获取专栏所有文章阅读权限及配套数据),如下图所示: 二、添加高度字段 本实验将二维数据…

k8s除了可以直接运行docker镜像之外,还可以运行什么? springboot项目打包成的压缩包可以直接运行在docker容器中吗?

Kubernetes&#xff08;k8s&#xff09;主要设计用于自动部署、扩展和管理容器化应用程序。虽然它与Docker容器最为密切相关&#xff0c;Kubernetes实际上是与容器运行时技术无关的&#xff0c;这意味着它不仅仅能够管理Docker容器。Kubernetes支持多种容器运行时&#xff0c;包…

潇洒郎:2024 IDEA、Pycharm获取最新激活码获取方式

IDEA获取最新激活码 https://idea.javatiku.cn/ 手机打开&#xff0c;看到验证码&#xff0c;30分钟有效&#xff0c;输入验证码 获取到最新激活码

Python Flask高级编程之RESTFul API前后端分离(学习笔记)

Flask-RESTful是一个强大的Python库&#xff0c;用于构建RESTful APIs。它建立在Flask框架之上&#xff0c;提供了一套简单易用的工具&#xff0c;可以帮助你快速地创建API接口。Flask-RESTful遵循REST原则&#xff0c;支持常见的HTTP请求方法&#xff0c;如GET、POST、PUT和DE…

PostgreSQL面试题-灿总题

面试题来源 &#xff1a;PostgreSQL学徒 PostgreSQL面试题集锦 已有的答案&#xff1a;Hehuyi_In 《PostgreSQL面试题集锦》学习与回答 一、MVCC 实现机制以及和 Oracle 的差异 ORACLE&#xff0c;MYSQL都是使用的UNDO来实现多版本并发控制&#xff0c;undo条目记录在从额外…

多维时序 | Matlab实现基于VMD-DBO-BiLSTM、VMD-BiLSTM、BiLSTM的多变量时间序列预测

多维时序 | Matlab实现基于VMD-DBO-BiLSTM、VMD-BiLSTM、BiLSTM的多变量时间序列预测 目录 多维时序 | Matlab实现基于VMD-DBO-BiLSTM、VMD-BiLSTM、BiLSTM的多变量时间序列预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 Matlab实现基于VMD-DBO-BiLSTM、VMD-BiLSTM、…

说一下JVM类加载机制?

Java中的所有类&#xff0c;都需要由类加载器装载到JVM中才能运行。类加载器本身也是一个类&#xff0c;而它的工作就是把class文件从硬盘读取到内存中。 在写程序的时候&#xff0c;我们几乎不需要关心类的加载&#xff0c;因为这些都是隐式装载的&#xff0c;除非我们有特殊…

HTB pwn Bad gradesRestaurant

Bad grades 没有开启ASLR 在功能2存在越界写,虽然有canary但是可以通过输入’-绕过。 输入数据可以利用python的struct解包成双精度浮点数,做了这些就是常规的ROP环节了。 exp from pwn import * def gd():gdb.attach(p)pause() def htd(hex_value):binary hex_value.to_b…

使用 Nginx 将部署多个子域名http服务重定向到https服务

首先在阿里云解析对应的子域名 打开自己的域名解析 点击添加记录 然后在nginx的配置文件下新增以下内容 # ssl证书地址,是你自己服务器上证书存放的地址 ssl_certificate /ssl/fullchain.cer; ssl_certificate_key /ssl/cert.key;#请按照以下协议配置 ssl_protocols…

JS基础(语法结构变量数据类型运算符流程控制)

JS基础(语法结构/变量/数据类型/运算符/流程控制) 目录 JS基础(语法结构/变量/数据类型/运算符/流程控制)什么是js&#xff1f;注释语法语法结构引入方式【1】script标签内部直接书写js代码【2】script标签src属性引入外部js代码 JS基础数据类型变量与常量变量的定义常量的定义…

OpenHarmony JS和TS三方组件使用指导

OpenHarmony JS和TS三方组件介绍 OpenHarmony JS和TS三方组件使用的是OpenHarmony静态共享包&#xff0c;即HAR(Harmony Archive)&#xff0c;可以包含js/ts代码、c库、资源和配置文件。通过HAR&#xff0c;可以实现多个模块或者多个工程共享ArkUI组件、资源等相关代码。HAR不…

calcite在flink中的二次开发,介绍解析器与优化器

calcite 在flink中的二次开发 1 CodeGen2 flink 语法扩展2.1 在进行 Rule 规则匹配时&#xff0c;放开对 Distinct 的限制2.2下面附上一个 利用codegen来生成所需类的例子&#xff1a; 3 flink使用calcite 生成解析器FlinkSqlParserImpl3.1 FlinkSqlParserImpl 的生成3.1.1 fli…

[SwiftUI]启动页LaunchScreen.storyboard中适配状态栏加安全区域的高度

如下图&#xff0c;我有一个需求。在启动页&#xff08;LaunchScreen.storyboard&#xff09;和引导页&#xff08;GuideView&#xff09;的黑色背景上&#xff0c;使用了同一张正方形图片。要求从启动页切换到引导页时&#xff0c;这两张相同的图片的过渡要无缝衔接&#xff0…

redis的缓存穿透,缓存并发,缓存雪崩,缓存问题及解决方案

缓存穿透 问题原因 解决方案 缓存并发 缓存雪崩 缓存失效时间设置一致导致的。 解决方案&#xff1a; 1&#xff09;方案一 2&#xff09;方案二 如何设计一个缓存策略&#xff0c;缓存热点数据&#xff1f;

【2024年湖北二建报考条件解析】不限专业,满足条件就能参加考试

【2024年湖北二建报考条件解析】不限专业&#xff0c;满足条件就能参加考试 2024年湖北二建报考疑问汇总&#xff0c;就近报考轻松搞定&#xff01; 2024年湖北省二级建造师/二建报考重点梳理 2024年湖北二建网上报名时间2月28号-3月12日。想要考二建的老铁千万不要错过一年一…

Centos安装图形化桌面环境

1.使用root远程登录最小化安装的虚拟机 2.执行命令yum groupinstall "X Window System" 这是安装窗口系统 3.执行命令yum grouplist" 检查安装的软件可可以安装的软件 4.执行命令yum groupinstall "Server with GUI" 这是安装图形化界面 5.执行命令sy…