热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

《Android内核剖析》笔记第5章进程间通信核心框架Binder

服务端:即服务提供者,比如android就提供了很多的系统服务,比如Alarm、WIFI、INPUT、LAYOUT_INFLATER、AC
  1. 服务端:即服务提供者,比如android就提供了很多的系统服务,比如Alarm、WIFI、INPUT、LAYOUT_INFLATER、ACTIVITY等;当然开发者也可以实现自己的服务,然后把服务开放给其他应用使用,在代码上服务接口必须继承 IInterface,服务具体实现类必须继承 Binder;

  2. Binder驱动:实际上他是一个遵从Linux设备驱动模型的虚拟驱动,设备节点为/dev/binder;他主要用来实现客户端和服务端请求的中转,其相关源码位于./frameworks/native/libs/binder/目录;

具体驱动的打开、监听是通过守护进程servicemana
ger完成,在./init.rc中定义,相关源码位于./frameworks/base/cmds/servicemanager/;

  1. 客户端:即服务消费者,要想调用其他进程中的功能,必须在本地有一个对远程对象的引用,且客户端和服务端必须遵从相同的接口和数据交换协议;而这两点就是实现IPC通信需要解决的最核心的两个问题;

为了简化服务提供者和消费者之间的开发和沟通成本,android系统提供了AIDL(Android Interface Definition Language)的工具支持,该工具可以把一个用于接口声明的aidl文件转换成一个Java文件,转换的过程就是要让该服务在代码层面自动符合Binder框架的设计规范,并自动解决好上面提到的2个核心问题中的第二点,生成好的Java文件其实包括了3个类:

服务接口类IXXX extends android.os.IInterface;

本地存根类IXXX.Stub  extends android.os.Binder implements IXXX;

远程代理类 IXXX.Stub.Proxy implements IXXX;

经历过EJB时代的同学们一定对上面的代码形式相当熟悉吧,哈哈!

以上文件生成好之后,服务提供者就可以专注于写具体的逻辑代码了,直接extends IXXX.Stub 实现具体的方法即可;

那是否可以不用aidl工具来生成代码呢?当然可以,如果你愿意的话完全可以自己来写相关的代码,只要符合Binder代码规范即可;

服务提供者使用的本地存根类IXXX.Stub中的核心方法

  1. public final boolean transact(int code, Parcel data, Parcel reply, int flags);实际上是父类Binder中的方法,因为是final的,所以子类是不能重载的,这也是Binder框架设计的一部分,因为他不允许开发者随意改变调用机制,该方法用于接受服务调用请求,但他自己并不直接处理这些请求,而是转交给onTransact方法(可由子类重载)来处理,这是android系统中非常重要的一种设计思想,被广泛用于各种场景,以后你看见onXXXX相关的方法一般都是相关的功能回调或子类重载点;

  2. protected boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags);

根据参数code判断该执行IXXX接口中的哪个具体业务方法,并且从data中按序取出数据作为具体业务方法的输入参数;

注意:从Parcel取出数据的顺序必须和存入数据(具体间后面IXXX.Stub.Proxy中业务方法的描述)的顺序一致,否则数据就乱套了,而这就是AIDL工具自动生成代码要解决的核心问题;

  1. public static IXXX asInterface(android.os.IBinder obj);将远程对象的引用转换成具体的业务接口,这里自动屏蔽了本地和远程调用的细节,因为服务提供方不仅可以被其他进程调用,还可以被自身进程内其他功能块调用;

服务消费者使用的远程代理类 IXXX.Stub.Proxy中的核心方法
身进程内其他功能块调用;

服务消费者使用的远程代理类 IXXX.Stub.Proxy中的核心方法


推荐阅读
  • 在Effective Java第三版中,建议在方法返回类型中优先考虑使用Collection而非Stream,以提高代码的灵活性和兼容性。 ... [详细]
  • importjava.io.*;importjava.util.*;publicclass五子棋游戏{staticintm1;staticintn1;staticfinalintS ... [详细]
  • 在Java开发中,保护代码安全是一个重要的课题。由于Java字节码容易被反编译,因此使用代码混淆工具如ProGuard变得尤为重要。本文将详细介绍如何使用ProGuard进行代码混淆,以及其基本原理和常见问题。 ... [详细]
  • IO流——字符流 BufferedReader / BufferedWriter 进行文件读写
    目录节点流、处理流读文件:BufferedReader的使用写文件:BufferedWriter的使用节点流处理流节点流和处理流的区别和联系字符流Buf ... [详细]
  • 处理Android EditText中数字输入与parseInt方法
    本文探讨了如何在Android应用中从EditText组件安全地获取并解析用户输入的数字,特别是用于设置端口号的情况。通过示例代码和异常处理策略,展示了有效的方法来避免因非法输入导致的应用崩溃。 ... [详细]
  • Maven + Spring + MyBatis + MySQL 环境搭建与实例解析
    本文详细介绍如何使用MySQL数据库进行环境搭建,包括创建数据库表并插入示例数据。随后,逐步指导如何配置Maven项目,整合Spring框架与MyBatis,实现高效的数据访问。 ... [详细]
  • 二维码的实现与应用
    本文介绍了二维码的基本概念、分类及其优缺点,并详细描述了如何使用Java编程语言结合第三方库(如ZXing和qrcode.jar)来实现二维码的生成与解析。 ... [详细]
  • 本文将从基础概念入手,详细探讨SpringMVC框架中DispatcherServlet如何通过HandlerMapping进行请求分发,以及其背后的源码实现细节。 ... [详细]
  • JavaScript 实现图片文件转Base64编码的方法
    本文详细介绍了如何使用JavaScript将用户通过文件输入控件选择的图片文件转换为Base64编码字符串,适用于Web前端开发中图片上传前的预处理。 ... [详细]
  • 本文探讨了如何在游戏启动画面中移除广告,特别是在游戏数据加载期间(大约5-6秒)广告会短暂显示的问题。通过调整XML布局和代码逻辑,可以实现广告的延迟加载或完全移除。 ... [详细]
  • 本文总结了近年来在实际项目中使用消息中间件的经验和常见问题,旨在为Java初学者和中级开发者提供实用的参考。文章详细介绍了消息中间件在分布式系统中的作用,以及如何通过消息中间件实现高可用性和可扩展性。 ... [详细]
  • 在Java开发中,如何利用ProcessBuilder类调用外部程序是一个常见的需求。本文将详细介绍ProcessBuilder类的使用方法,并提供示例代码帮助你更好地理解和应用。 ... [详细]
  • 长期从事ABAP开发工作的专业人士,在面对行业新趋势时,往往需要重新审视自己的发展方向。本文探讨了几位资深专家对ABAP未来走向的看法,以及开发者应如何调整技能以适应新的技术环境。 ... [详细]
  • 本文探讨了如何通过优化 DOM 操作来提升 JavaScript 的性能,包括使用 `createElement` 函数、动画元素、理解重绘事件及处理鼠标滚动事件等关键主题。 ... [详细]
  • 本文详细介绍了在Linux操作系统上安装和部署MySQL数据库的过程,包括必要的环境准备、安装步骤、配置优化及安全设置等内容。 ... [详细]
author-avatar
莫轻松
这个家伙很懒,什么也没留下!
RankList | 热门文章