Android 基础技术——Framework

news2024/12/23 3:40:35

笔者希望做一个系列,整理 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.coloradmin.cn/o/1461193.html

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

相关文章

2.20 Qt day1

一. 思维导图 二. 消化常用类的使用&#xff0c;以及常用成员函数对应的功能 按钮类QPushButton&#xff1a; mywidget.h&#xff1a; #ifndef MYWIDGET_H #define MYWIDGET_H#include <QWidget> #include<QPushButton>//按钮类 #include<QIcon>class MyW…

vscode 插件 Marp for VS Code 制作 ppt

话不多说&#xff0c;直接上图 用它来写幻灯片&#xff0c;简直不要太好用&#xff0c;如果你一直使用 markdown 语法写笔记的话&#xff0c;那么做 ppt 对你来说简直就是喝水&#xff1b; 在vscode 上面直接装一个Marp for VS Code插件就可以了 基本使用方法步骤 crtl win …

Flutter自定义tabbar任意样式

场景描述 最近在使用遇到几组需要自定义的tabbar或者类似组件&#xff0c;在百度查询资料中通常&#xff0c;需要自定义 TabIndicator extends Decoration 比如上图中的带圆角的指示器这样实现 就很麻烦&#xff0c; 搜出来的相关也是在此之处上自己画&#xff0c;主要再遇…

OpenLDAP接入NineData SSO

本文面向使用 OpenLDAP 管理人员账户信息的企业&#xff0c;提供将 OpenLDAP 接入单点登录&#xff08;SSO&#xff09;的最佳实践指南&#xff0c;以实现统一认证和授权管理。通过集成 OpenLDAP、phpLDAPadmin、Keycloak&#xff0c;您可以轻松通过 SSO 功能登录 NineData。 …

Android13 编译ninja failed with: exit status 137

描述 现象很奇怪&#xff0c;主机是ubuntu 18.04&#xff0c; 内存有32G&#xff0c;并且系统中有两份Android13代码&#xff0c; 有一份编译正常&#xff0c;另外一份编译不正常&#xff0c;一度以为是因为下载源码不齐全导致&#xff0c;后面仔细看日志&#xff0c;原来是内…

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

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

uniapp运动课程健身打卡系统微信小程序

考虑到实际生活中在我来运动管理方面的需要以及对该系统认真的分析,将系统分为小程序端模块和后台管理员模块&#xff0c;权限按管理员和用户这两类涉及用户划分。 (a) 管理员&#xff1b;管理员使用本系统涉到的功能主要有&#xff1a;首页、个人中心、用户管理、课程类别管理…

计算机设计大赛 深度学习动物识别 - 卷积神经网络 机器视觉 图像识别

文章目录 0 前言1 背景2 算法原理2.1 动物识别方法概况2.2 常用的网络模型2.2.1 B-CNN2.2.2 SSD 3 SSD动物目标检测流程4 实现效果5 部分相关代码5.1 数据预处理5.2 构建卷积神经网络5.3 tensorflow计算图可视化5.4 网络模型训练5.5 对猫狗图像进行2分类 6 最后 0 前言 &#…

静态时序分析:保持时间分析

相关阅读 静态时序分析https://blog.csdn.net/weixin_45791458/category_12567571.html?spm1001.2014.3001.5482 在静态时序分析中&#xff0c;保持时间检查约束了触发器时钟引脚&#xff08;时钟路径&#xff09;和输入数据引脚&#xff08;数据路径&#xff09;之间的时序关…

虚拟机安装Centos7迷你版

虚拟机安装Centos7迷你版 迷你版较常规版精简了很多功能&#xff0c;所以体积也小了很多&#xff0c;喜欢自定义安装的可以选择迷你版 参考文章&#xff1a; VirtualBox虚拟机安装Centos7详细教程图解 网卡配置参考文章 下载Centos迷你版镜像 安装镜像 下载镜像 阿里云Cen…

【Python】【VS Code】VS Code中python.json和setting.json文件配置说明

目录 1. python.json配置 2. setting.json配置 3. 解决中文乱码 4. 实现效果 1. python.json配置 python.json 获取步骤&#xff1a;文件 -> 首选项 -> 配置用户代码片段 -> python 此为VS Code的头文件设置&#xff0c;复制以下内容到 python.json {"HEADER…

【爬虫JS逆向-工具篇】浏览器内存漫游加密参数Hook实战教程

文章目录 1. 写在前面2. 环境搭建2. 加密定位实战 【作者主页】&#xff1a;吴秋霖 【作者介绍】&#xff1a;Python领域优质创作者、阿里云博客专家、华为云享专家。长期致力于Python与爬虫领域研究与开发工作&#xff01; 【作者推荐】&#xff1a;对JS逆向感兴趣的朋友可以关…

如何高效测试APP,快速定位bug?

一般提到测试&#xff0c;很多人会想到考试&#xff0c;但任意一个APP面世之前&#xff0c;也都需要多次测试&#xff0c;确保可以正常使用之后才会面世。有的公司会有专门的测试工程师&#xff0c;而在一般的互联网公司&#xff0c;大多由产品经理、工程师、设计师等兼职&…

vulnhub练习 DC-1复现及分析

一、搭建环境 1.工具 靶机&#xff1a;DC-1 192.168.200.17 攻击机&#xff1a;kali 192.168.200.13 2.注意 攻击机和靶机的网络连接方式要相同&#xff0c;另外DC-1的网络连接方式我这里采用NAT模式&#xff0c;是与kali的网络连接模式相同的&#xff08;当然亦可以选用桥…

unity学习(28)——登录功能

有之前注册的知识&#xff0c;登录就很容易处理了。 登陆成功返回id&#xff1a; 登录失败返回null&#xff1a; 测试同一账号不能重复登陆&#xff01;登录成功后最好可以跳到新的场景中 结果是好的&#xff0c;去服务器看一下对应部分的代码&#xff0c;可见&#xff0c;登…

多端开发围炉夜话

文章目录 一、多端开发 一、多端开发 uni-app 官网 UNI-APP中的UI框架&#xff1a;介绍常用的UI框架及其特点 uView UIVant WeappColor UIMint UI uniapp嵌入android原生开发的功能 uniapp使用安卓原生sdk uni-app中的uni.requireNativePlugin Qt for iOS Qt for Android

Deep Layer Aggregation(CVPR 2018)原理与代码解析

paper&#xff1a;Deep Layer Aggregation official implementation&#xff1a;https://github.com/ucbdrive/dla third-party implementation&#xff1a;https://github.com/huggingface/pytorch-image-models/blob/main/timm/models/dla.py 本文的创新点 骨干网络的设计…

Spring Boot利用Kaptcha生成验证码

生成验证码 我们在登录或注册某个网站的时候&#xff0c;会需要我们输入验证码&#xff0c;才能登录注册&#xff0c;那么如何生成验证码呢&#xff1f;其实&#xff0c;生成验证码我们可以用Java Swing在后台内存里的区域画一个出来&#xff0c;但是非常麻烦&#xff0c;所以…

Linux系统——nginx服务介绍

一、Nginx——高性能的Web服务端 Nginx的高并发性能优于httpd服务 1.nginx概述 Nginx是由1994年毕业于俄罗斯国立莫斯科鲍曼科技大学的同学为俄罗斯rambler.ru公司开发的&#xff0c;开发工作最早从2002年开始&#xff0c;第一次公开发布时间是2004年10月4日&#xff0c;版本…

KubeSphere 镜像构建器(S2I)服务证书过期解决方案

目前 KubeSphere 所有 3.x.x 版本&#xff0c;如果开启了 DevOps 模块并使用了镜像构建器功能&#xff08;S2I&#xff09;都会遇到证书过期问题。 解决方法 已开启 DevOps 模块 下载这个更新 S2I 服务证书压缩包&#xff0c;上传到任一可以访问 K8s 集群的节点&#xff1b; …