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差不多的概念,不过它是管理窗口的系统服务。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用Flex布局在HTML中实现双行夹批效果

古代小说中经常有评点和批注&#xff0c;为了区别正文和批注&#xff0c;一般将批注排版成双行夹批的形式。我们知道&#xff0c;在Word中只需要先选择批注文字&#xff0c;然后通过“开始”菜单“段落”面板上字符缩放工具组里的“双行合一”命令&#xff0c;就可以很容易实现…

Android13 针对low memory killer内存调优

引入概念 在旧版本的安卓系统中&#xff0c;当触发lmk&#xff08;low memory killer&#xff09;的时候一般认为就是内存不足导致&#xff0c;但是随着安卓版本的增加lmk的判断标准已经不仅仅是内存剩余大小&#xff0c;io&#xff0c;cpu同样会做评判&#xff0c;从而保证设备…

vue实现列表自动无缝滚动列表

大家好&#xff0c;今天给大家分享的知识是vue基于vue-seamless-scroll实现自动无缝滚动列表 一、实现自动滚动 最近在开发过程中遇到一个问题&#xff0c;就是需要实现自动滚动列表&#xff0c;效果图如下 就是这样一个列表在自动循环展示。在这里我是运用的 vue-seamless-sc…

HTTP的详细介绍

目录 一、HTTP 相关概念 二、HTTP请求访问的完整过程 1、 建立连接 2、 接收请求 3、 处理请求 3.1 常见的HTTP方法 3.2 GET和POST比较 4、访问资源 5、构建响应报文 6、发送响应报文 7、记录日志 三、HTTP安装组成 1、常见http 服务器程序 2、apache介绍和特点 …

专转本的三道难关

道阻且长&#xff0c;路途中的艰辛只有亲身经历过转本的人才能感同身受&#xff0c;这三道难关也是每个升本人都会经历的。尤其是最后一个&#xff08;o(╥﹏╥)o&#xff09;&#xff01;&#xff01;&#xff01; 01 选择大于努力 很多人想专转本都是为了圆本科的梦&a…

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

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

实现RAG管道中的上下文压缩和过滤

每日推荐一篇专注于解决实际问题的外文,精准翻译并深入解读其要点,助力读者培养实际问题解决和代码动手的能力。 欢迎关注公众号(NLP Research),及时查看最新内容 原文标题:Implement Contextual Compression And Filtering In RAG Pipeline 原文地址:https://medium.…

新版AI系统ChatGPT源码支持GPT-4/支持AI绘画去授权

源码获取方式 搜一搜&#xff1a;万能工具箱合集 点击资源库直接进去获取源码即可 如果没看到就是待更新&#xff0c;会陆续更新上 新版AI系统ChatGPT网站源码支持GPT-4/支持AI绘画/Prompt应用/MJ绘画源码/PCH5端/免授权&#xff0c;支持关联上下文&#xff0c;意间绘画模型…

题目 1032: [编程入门]自定义函数之字符串连接

问题描述&#xff1a; 写一函数&#xff0c;将两个字符串连接 样例输入&#xff1a; 123 abc 样例输出&#xff1a; 123abc 代码分析&#xff1a; 这段代码的主要目的是将两个字符串连接起来&#xff0c;并输出结果。它使用了 fgets 函数获取用户输入的两个字符串&#…

Spring RabbitMQ 配置多个虚拟主机(vhost)

文章目录 前言一、相关文章二、相关代码1.yml文件配置2.RabbitMq配置类3.接收MQ消息前言 在日常开发中,同时需要用到RabbitMQ多个虚拟机(vhost)。应用场景:需要接收多个交换机的数据,而交换机都在不同的虚拟机(vhost) 一、相关文章 Docker安装RabbitMQ 【SpringCloud…

[极客挑战2019]HTTP

这道题考察的是http请求头字段的含义和使用&#xff1b; 具体如下 Referer:来源地址 User-Agent:客户端配置信息&#xff1a;浏览器类型、版本、系统类型等 X-Forwarded-For:代理地址&#xff0c;即数据发出的地址 开始解题&#xff1a;&#xff08;对我这初学者真的烧脑&a…

Qt应用-视频播放器实例

本文讲解Qt视频播放器应用实例。 实现功能 视频的播放暂停、拖动进度控制,声音控制播放列表控制播放区域的暂停控制,全屏控制等。 界面设计 <?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"><class>frmVide…

深度学习在时间序列预测的总结和未来方向分析

2023年是大语言模型和稳定扩散的一年&#xff0c;时间序列领域虽然没有那么大的成就&#xff0c;但是却有缓慢而稳定的进展。Neurips、ICML和AAAI等会议都有transformer 结构(BasisFormer、Crossformer、Inverted transformer和Patch transformer)的改进&#xff0c;还出现了将…

压缩感知(Compressed Sensing)的MATLAB仿真实现

在前一篇文章&#xff1a;正交匹配追踪&#xff08;Orthogonal Matching Pursuit, OMP&#xff09;的MATLAB实现中&#xff0c;我们介绍了针对稀疏信号进行压缩感知的MATLAB仿真。 本篇我们介绍一下针对的是原始的非稀疏信号&#xff0c;看看如何进行处理。 本文中&#xff0c;…

设计模式面试系列-02

1. Java 中工厂模式有什么优势? 1、工厂模式是最常用的实例化对象模式,是用工厂方法代替new操作的一种模式。 2、利用工厂模式可以降低程序的耦合性,为后期的维护修改提供了很大的便利。 3、将选择实现类、创建对象统一管理和控制,从而将调用者跟我们的实现类解耦。 2. …

读懂2024年数字孪生发展新趋势!十大权威白皮书放送!

2024年&#xff0c;数字孪生 该往哪些方向走&#xff1f; 新技术的不断涌现 又会带来怎样的行业变迁 …… 在开工之际&#xff0c;我们整理了 51WORLD主导、参编的 十大权威数字孪生白皮书、行业报告 以及产业优秀案例集 分享给想要提升自我的朋友们 读完这些 上面看似…

嵌入式23——IO

时间获取: 1.time time_t time(time_t *tloc);// 定义 time_t t 用来存放秒数&#xff0c;不能定义一个time_t *t 流指针 原因&#xff1a;流指针为野指针&#xff0c;它的指向不明确&#xff0c;没有一块空间用来存放秒数 即使将流指针初始为NULL&#xff0c;也…

singularity-ce-4.1.0 + go 完整安装步骤,及报错解决

singularity-ce-4.1.0 go 1.20 完整安装步骤. 解决bug: checking: host Go compiler (at least version 1.13)... not found! mconfig: could not complete configuration服务器基础环境&#xff1a; 阿里云服务器&#xff1a; > lsb_release -a LSB Version: :core-4.…

道可云元宇宙每日资讯|杭州:重点培育元宇宙、智能型机器人等

道可云元宇宙每日简报&#xff08;2024年2月20日&#xff09;讯&#xff0c;今日元宇宙新鲜事有&#xff1a; 杭州&#xff1a;重点培育元宇宙、智能型机器人等 昨日&#xff0c;杭州市人民政府发布《关于进一步推动经济高质量发展的若干政策》。政策指出&#xff0c;以通用人…

不止提升免疫力?NMN或可预防、缓解支原体肺炎造成的肺部损伤

近期&#xff0c;全国多地进入呼吸道疾病高发季&#xff0c;支原体肺炎等相关话题频频登上各大热搜榜。 发烧、咳嗽、嗓子疼、肺炎……支原体肺炎的战线拉得挺长&#xff0c;过年了都还有不少人纷纷中招&#xff1a;发热、咳嗽&#xff0c;来来回回拖了一两周才好&#xff0c;…