Framework学习:周末小总结以及Binder基础

Framework学习:周末小总结以及Binder基础

文章目录

背景:

对上周学的一些源码和一些流程进行回顾,主要在系统启动方面,还有一些binder的基础,因为binder涉及到的知识面太多了,可能流程会比较长而且会插入一下别的东西的学习。

一、Android系统架构概览

  1. 层次结构 (以音频为例):
    硬件层 → 驱动层 → HAL层(硬件抽象层) → Native层(C/C++) → JNI层 → Java Framework层 → 应用层
    • HAL层:对硬件进行抽象封装,提供统一接口给Native层调用,隔离硬件差异。
    • Framework层:包含大量系统服务(如Audio、Bluetooth、WiFi、WMS等),提供Java API给应用调用。
    • AOSP vs Framework:AOSP是Android开源项目的完整源码,Framework是AOSP中的核心框架部分(含系统服务、API等)。

二、Binder机制:跨进程通信的核心

1. 基本定位

Binder是Android最核心的IPC机制,连接系统中各个进程(如应用进程与系统服务进程),解决进程内存隔离导致的通信问题。

2. 与相关技术的关系

  • AIDL:Android接口定义语言,自动生成Binder通信的Java/C++代码(代理Proxy与Stub),简化跨进程调用实现。
  • HIDL:硬件接口定义语言,用于HAL层与Framework层的通信,底层依赖Binder机制(Android 8.0后逐步替代旧的HAL与Binder交互方式)。

3. 核心特性

  • 高效传输:通过内存映射(mmap)实现一次数据拷贝(传统IPC需两次),适合高频通信(如系统服务调用)。
  • C/S架构
    • Server(服务端):提供服务的进程(如SystemServer),通过Binder注册服务。
    • Client(客户端):使用服务的进程(如应用),通过Binder获取Server的代理对象(Proxy)。
    • Binder驱动:内核层中间件,负责转发请求、管理连接、验证进程身份(UID/PID)。
  • 安全性:通信时自动携带进程UID/PID,Server可基于权限控制是否响应(如SMS服务校验发送权限)。

4. 运行空间

  • Binder跨用户空间与系统空间工作:
    • 系统空间:idle进程及以上的内核态进程。
    • 用户空间:init进程(第一个用户空间进程)、应用进程、系统服务进程等,Binder的客户端/服务端实现运行在此。

三、核心进程与启动流程

  1. Init进程

    • 用户空间第一个进程,通过加载init.rc脚本启动关键进程(如ServiceManager、Zygote)。
    • 常驻后台,通过epollwait阻塞等待事件(若无任务则休眠),保证系统稳定性。
  2. ServiceManager

    • Binder机制的"服务注册表",管理所有系统服务的注册与查询(Client需先通过它获取Server的Binder代理)。
    • ServiceManager 是 Android 中第一个注册的 Binder 服务,自身没有 Proxy,直接通过binder_loop循环处理请求。
      其他服务(如 AMS、WMS)必须先向 ServiceManager 注册(addService()),Client 需先通过 ServiceManager 查询(getService())获取目标服务的 Binder 引用。
      补充流程:Client→ServiceManager(查服务)→目标 Server(通过 Binder 通信)。
  3. Zygote进程

    • 作用:孵化应用进程(通过fork快速创建新进程,共享虚拟机资源)。
    • 特性:同时运行Java与Native(C/C++)代码:
      • Native层:启动ART虚拟机(设置堆大小等参数,参数来自设备property文件),ART是Android的虚拟机(替代传统JVM,更适合移动设备)。
      • Java层:执行Zygote.main(),读取启动参数,准备应用进程孵化环境。
java 复制代码
zygote.main() {
    // 1. 初始化启动参数
    // 从启动进程的参数(如init.rc传递的args)中解析配置
    // 包括:进程名称、虚拟机启动参数、预加载资源列表路径等
    String[] argv = parse启动参数(); // 解析init进程传递的命令行参数
    String processName = 从argv中提取进程名(); // Zygote进程名通常为"zygote"或"zygote64"

    // 2. 启动Native层运行时环境(AndroidRuntime)
    // 这是连接Java层与Native层的桥梁,负责初始化底层资源
    AndroidRuntime runtime = new AndroidRuntime();
    runtime.initNativeEnv(); // 初始化Native层环境(如C库、线程池等)

    // 3. 启动ART虚拟机(Android Runtime)
    // 虚拟机参数从系统属性(build.prop等)读取,不同设备配置不同
    // 例如:dalvik.vm.heapstartsize(初始堆大小)、dalvik.vm.heapsize(最大堆大小)
    String[] vmArgs = 从系统属性读取虚拟机参数(); 
    runtime.startVm(vmArgs); // 启动ART虚拟机(基于C/C++实现,替代传统JVM)
    // 注:ART是Android专用虚拟机,支持AOT编译,性能优于JVM,更适合移动设备

    // 4. 注册JNI方法(Java与Native代码的映射)
    // 静态注册:通过方法名规则(Java_包名_类名_方法名)自动关联
    // 动态注册:通过RegisterNatives()主动注册映射关系(更高效,系统框架常用)
    runtime.registerJniMethods(); // 注册Framework层核心类的JNI方法
    // 例如:java.lang.String的native方法与C++的String.cpp实现关联

    // 5. 预加载核心类与资源(关键优化点)
    // 提前加载系统Framework类(如android.app.*)、主题资源、共享库等
    // 后续通过fork创建应用进程时,可直接复用这些已加载资源,减少重复开销
    preloadClasses(); // 预加载系统类(从preloaded-classes文件读取列表)
    preloadResources(); // 预加载系统资源(如framework-res.apk)

    // 6. 启动Socket服务,等待孵化新进程的请求
    // Zygote通过本地Socket接收AMS(ActivityManagerService)的进程创建请求
    ZygoteServer server = new ZygoteServer();
    server.createSocket(); // 创建本地Socket(路径通常为/dev/socket/zygote)
    server.runSelectLoop(); // 进入循环,阻塞等待新进程孵化请求
    // 收到请求后通过fork()创建子进程(应用进程),并复用Zygote的虚拟机资源
}

fork后,子进程(应用进程)会调用handleChildProc(),销毁 Zygote 的 Socket 连接(避免冲突),重置进程 ID 和权限。

启动应用进程的主线程(ActivityThread.main()),通过 JNI 调用ActivityThread.attach(),与 AMS 建立 Binder 通信(注册应用进程)。

补充:Zygote 通过 "写时复制(COW)" 机制复用内存,fork后仅当子进程修改数据时才复制内存页,优化资源占用。

四、Framework与Native层的关系

  1. Native层定位

    • 属于用户空间,用C/C++编写,处理高性能需求场景(如大图片跨进程传输、音视频编解码)。
    • 与Framework层通过JNI(Java Native Interface)交互:JNI负责映射Java方法与Native函数,实现跨语言调用。
  2. 混淆点澄清

    • Native层≠系统空间:Native是用户空间中使用C/C++的代码层,与Java层同属用户空间。
    • JVM并非应用底层:Android应用依赖ART虚拟机(Native层实现),JVM是传统Java虚拟机,不适用于Android。
  3. 具体案例

    • 以 "获取屏幕亮度" 为例:
      App 调用Settings.System.getInt(getContentResolver(), SCREEN_BRIGHTNESS)(Java Framework)→
      通过 JNI 调用android_os_Settings_System.cpp(Native 层)→
      调用 HAL 层的ILightService(通过 HIDL/Binder)→
      最终操作硬件驱动。

五、Framework开发核心与学习思路

  1. Framework开发目的

    解决系统级问题(如WMS处理多应用闪屏),优化系统服务性能或扩展功能。

  2. 学习路径

    • 源码阅读:理解系统服务(如AMS、WMS)的实现逻辑,重点关注Binder通信流程。
    • 实践:编写AIDL接口,编译运行验证跨进程调用;修改Framework源码(如系统服务),重新编译验证效果。
    • 架构理解:梳理各层依赖关系(如HAL→Native→Framework的调用链),明确Binder在其中的桥梁作用。
相关推荐
用户20187928316715 分钟前
Dialog不消失之谜——Android窗口系统的"平行宇宙"
android
用户2018792831671 小时前
Dialog 不消失之谜:一场来自系统底层的 "越狱" 行动
android
pengyu1 小时前
【Kotlin系统化精讲:陆】 | 数据类型之类型系统及精髓:安全性与智能设计的哲学
android·kotlin
用户2018792831672 小时前
DecorView添加到Window和直接用WindowManger添加View的差异?
android
叽哥2 小时前
flutter学习第 16 节:项目实战:综合应用开发(上)
android·flutter·ios
开发者如是说2 小时前
[中英双语] 如何防止你的 Android 应用被破解
android·安全
今天的风儿好耀眼3 小时前
关于Google Pixel,或者安卓16,状态栏颜色无法修改的解决方案
android·java·安卓
Digitally4 小时前
使用 6 种方法将文件从 Android 无缝传输到iPad
android·cocoa·ipad
AOwhisky4 小时前
项目实战2——LAMP_LNMP实践
android