Ahao's Technical Blog Ahao's Technical Blog
首页
  • 001.基础篇
  • 002.玩转AOSP篇
  • 003.学穿Binder篇
  • 004.基础组件篇
  • 005.系统启动过程分析
  • 006.Hal开发入门与实践
  • 007.显示系统
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

阿豪讲Framework

不积跬步无以至千里
首页
  • 001.基础篇
  • 002.玩转AOSP篇
  • 003.学穿Binder篇
  • 004.基础组件篇
  • 005.系统启动过程分析
  • 006.Hal开发入门与实践
  • 007.显示系统
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 基础篇

  • 玩转AOSP篇

  • 学穿Binder篇

    • 000.Binder 专题导学 —— 如何深入掌握 Binder
      • 为什么要学习和掌握 Binder
      • 学习 Binder 的预备知识
      • 了解 Binder 基本原理
      • C 层
      • 驱动分析
      • C++ 层分析
      • Java 层分析
      • 疑难问题
    • 001.学习 Binder 的预备知识
    • 002.Binder 基本原理
    • 003.Binder 程序示例之 C 语言篇
    • 004.Binder 服务注册过程情景分析之 C 语言篇
    • 005.Binder 服务获取与使用过程情景分析之C语言篇
    • 006.Android Binder 驱动框架设计与分析
    • 007.Binder 驱动情景分析之 ServiceManager 启动过程
    • 008.Binder 驱动情景分析之服务注册过程
    • 009.Binder 驱动情景分析之服务获取与使用过程
    • 010.Binder 程序示例之 C++ 篇
    • 011.Binder C++ 程序分析之主要类解析
    • 012.Binder 服务注册过程情景分析之 C++ 篇
    • 013.Binder 服务获取与使用过程情景分析之C++篇
    • 014.Binder 程序示例之 aidl-cpp 篇
    • 015.添加 Android Native 系统服务
    • 016.添加 Native 系统服务回调
    • 017.Binder 程序示例之 Java 篇
    • 018.Binder Java 层初始化
    • 019.Binder Java 层服务注册过程分析
    • 020.Binder Java 层服务获取与使用过程分析
    • 021.添加 Java 系统服务
    • 022.Android Java 系统服务框架与第三方 App 使用自定义 Java 系统服务
    • 023.添加 Java 系统服务回调
    • 024.AIDL 数据类型详解之 Java 篇
    • 025.AIDL 数据类型详解之 C++ 篇
    • 026.Java 调用 Native 服务
    • 027.Native 调用 Java Binder 服务
    • 028.AIDL 关键字 in out inout oneway 解析
    • 029.Binder 驱动 Debug 入门指南
    • 030.Binder 匿名服务源码分析
    • 031.Binder 中的 Parcel 数据结构分析(C++)
    • 032.Binder 中的 Parcel 数据结构分析(Java)
    • 033.Binder 多线程情景分析
    • 034.Binder 线程池溢出问题
    • 035.Binder 代理对象泄露问题分析
    • 036.Binder 死亡通知情景分析
    • 037.Binder 异常处理机制
    • 038.Binder 系统源码演进
    • 039.Binder 面试题汇总
    • 补充——LocalService
  • 基础组件篇

  • 系统启动过程分析

  • Hal开发入门与实践

  • 显示系统

  • Framework
  • 学穿Binder篇
阿豪
2023-07-06
目录

000.Binder 专题导学 —— 如何深入掌握 Binder

Hello,Hello 大家好,这里是“写给应用开发的 Android Framework 教程”,我是阿豪,今天我们学习的内容是 “Binder 专题导学——如何深入掌握 Binder”。

首先我们看到的是学穿 Binder 篇专题的大纲:

我会把这个思维导图放到课程资料中,我们可以把这个思维导图作为一个向导,来指引我们 Binder 的学习。

# 为什么要学习和掌握 Binder

在学习之前我们要明白我们为什么要学习和掌握 Binder?主要有以下几点原因:

  • Binder 是整个 Android 的基石,所有的系统服务都是基于 Binder,Android 四大组件的底层实现离不开 Binder。如果你要成为 Android 领域的资深研发人员,Binder 是必须要深入掌握的知识之一。
  • 系统开发领域,自定义 Native 和 Java 系统服务是日常工作之一,需要我们熟悉 Android 中与 Binder 相关的类库以及相关的辅助工具。
  • 对于应用开发,ANR 冻屏 卡顿 卡死等偶现 BUG 很可能与 Binder 调用相关,解决这些 bug,需要我们深入掌握理解 Binder 的内部原理。

# 学习 Binder 的预备知识

Binder 是一个 RPC(Remote Procedure Call) 框架,涉及的技术点横跨了 内核 Native JNI Java 四层,学习 Binder 需要较为广泛的知识面,针对大部分 Android 应用开发的知识体系,我总结了以下几点必须要掌握的预备知识:

  • 首先,我们需要入门 Linux 驱动开发,Binder 是一个字符驱动,了解驱动的基本开发流程是阅读 Binder 驱动源码的前提条件
  • 其次,我们需要了解 Linux 内核中常用数据结构的基本使用,Binder 驱动中涉及了很多内核中的数据结构,我们需要了解如何使用这些数据结构
  • 接着,我们需要学习虚拟内存,这是掌握 Binder 工作原理的理论基础
  • 然后,我们需要学习 Linux 文件访问接口,学习了这部分知识才能知道 Binder 驱动是怎么被访问的
  • 最后,我们需要学习 JNI 编程,因为 Binder 的 Java 层中有大量的 JNI 函数

# 了解 Binder 基本原理

有了预备知识的铺垫,我们就可以开始学习 Binder 的基本理论了,主要从 IPC(跨进程数据传输) 和 RPC(远程过程调用) 两个角度来理解 Binder 的工作原理。这部分内容我们会在后续课程中详细分析。

# C 层

在了解了 Binder 基本原理后,我们就可以开始写应用了。

写应用之前,我们要明白,Binder 是一个字符驱动,linux 系统提供了 open ioctl mmap close 等系统调用来使用 Binder 驱动,这些函数是应用层最底层的操作了。

AOSP 源码中有一个 binder.c 源文件,对 open ioctl mmap close 等函数做了封装以适应和简化 Binder 应用层程序的编写。源码中有一个 binder 的测试程序 bctest.c 以及系统服务管家 servicemanager(Android10 及以前) 都是基于 binder.c 的封装实现的。

相比 libbinder 库 C++ 的封装,binder.c 会简单不少 ,方便初学者理解 binder 应用层工作流程。

我们可以模仿 bctest.c service_manager.c 写一个完整的 Binder 应用层 demo。

这个工作已经有大佬完成了:

https://github.com/weidongshan/APP_0003_Binder_C_App

但是也有一些问题,这个代码是基于 Android5 的,稍微有点老了,我在以上实现的基础上做了一些修改和适配工作,使得代码可以在 Android10 上跑起来:

https://github.com/yuandaimaahao/AndroidFrameworkTutorial/tree/main/3.%E5%AD%A6%E7%A9%BFBinder%E7%AF%87/%E6%BA%90%E7%A0%81/BinderCDemo

通过对这个示例程序的分析,我们可以学习到:

  • Binder 应用层涉及的三个进程
  • Binder 应用层工作的流程
  • Binder 与驱动交互的数据结构

# 驱动分析

在熟悉了 C 层以后,我们就可以开始学习 Binder 驱动了。

结合 C 层的示例来分析驱动的实现,主要搞清楚:

  • 服务注册,获取,使用三个情景下,内核中的工作流程
  • 服务注册,获取,使用三个情景下,内核中各种数据结构的变化

通过驱动的分析,我们就能彻底搞懂 Binder 的内部原理了,包括了:

  • 数据传输大小的限制
  • 数据是怎么跨进程传输的
  • 一次拷贝原理
  • 进程/线层的阻塞和唤醒是如何实现的。

# C++ 层分析

C++ 层有一个 libbinder 库,这个库也是对 open ioctl mmap close 这些系统调用的封装,相比 binder.c 的封装更为完善,功能更多,内部实现更为复杂。

首先我们要写一个基于 libbinder 库的 Demo (opens new window)。基于这个 Demo, 我们来分析 libbinder 库中的类和函数,理清楚服务的注册获取使用三大流程。

基于这个 Demo,我们还需要分析 libbinder 中对几个特殊场景的处理:

  • 死亡通知
  • 多线程
  • 匿名服务

# Java 层分析

首先,我们先写一个 Java 层的完整示例。我们要明白 Java 层只是一层马甲,其核心功能都是通过 JNI 调用到 libbinder 库实现的,所以我们需要对 JNI 编程有基本的了解。

接着我们基于这个示例,分析三个情景下的执行过程与各个类与函数的流程与功能:

  • Java 层初始化
  • 服务注册过程分析
  • 服务获取与使用过程分析

当然还有一些其他高级特性也需要我们分析:

  • AIDL 中 in out inout oneway 的分析
  • Parcel 数据结构分析
  • Java 层死亡通知
  • Java 层多线程分析
  • 匿名服务

# 疑难问题

不论是应用开发还是系统开发我们都会遇到一些棘手的 bug,很多时候这些 bug 都和 binder 有关,总结起来,大概可以分为几类:

  • 死锁
  • 线程池满了
  • 代理对象内存泄露
  • 传输数据过大
  • 关键方法内发起 Binder 同步调用导致卡顿

这类 bug 很多都难以复现,很多时候都不了了之了,导致拥有这部分经验的同学很少。后续课程中,我们会逐一进行分析。

016.2025 Android Studio For Platform 上手指南
001.学习 Binder 的预备知识

← 016.2025 Android Studio For Platform 上手指南 001.学习 Binder 的预备知识→

最近更新
01
如何调试 SurfaceFlinger
10-05
02
SurfaceFlinger 概述
10-05
03
HWC 接口分析
10-05
更多文章>
Theme by Vdoing | Copyright © 2020-2025 AHao Framework | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式