当前位置: 首页 > news >正文

Android开发之漫漫长途 Ⅷ——Android Binder(也许是最容易理解的)

前言

我们在上一篇中比较详尽的介绍了Android的消息机制,不过有一些内容我们在不理解Android Binder的话是无法讲解清楚的。对于初学Android的朋友而言,最难却又最想掌握的恐怕就是Binder机制了,因为Android系统基本上可以看作是一个基于Binder通信的C/S架构。 Binder就像网络一样,把系统的各个部分连接在了一起,因此它是非常重要的。我们下面会Android Binder机制进行从上到下从易到难的分层次讲解,从而既能让初学者对Binder有一定认识,也能让有一定Android基础的人获得收获。
注:下文中的源码均出自android-6.0.0_r5

Binder概述

对于初学者来说,深入Android Binder机制是非常不明智的。Android Binder机制大都涉及Java层、Native层、驱动层这三三个方面,对于初学者来说想啃这三块硬骨头很容易磕着牙。我们这这一节概述从以下几个方面让你从比较宏观的角度理解Android Binder。

进程

在该系列博客中的第一章我们就说起了Android进程相关问题,Android故意弱化了进程的概念,而用相对容易理解的四大组件。可是我们在稍微深入Android的时候,那么进程是绕不过的。默认情况下,同一个应用程序中的所有组件运行在同一个进程中,而且绝大多数的应用程序也都是这样的。这个默认进程是用这个应用的包名来命名的。

进程间通信

我们在运行App的时候经常需要使用一些系统服务,比如剪切板服务,而剪切板服务是运行在SystemServer进程中的。那我们的App是怎么使用剪切板服务的呢,我们都知道进程是相互独立的,静态变量等等都无法共用。这就涉及到进程间的通信了,即IPC。我们都知道Android是基于Linux内核的,那我们简单介绍下Linux下的几种IPC机制。

管道(Pipe)

管道是由内核管理的一个缓冲区,相当于我们放入内存中的一个纸条。管道的一端连接一个进程的输出。这个进程会向管道中放入信息。管道的另一端连接一个进程的输入,这个进程取出被放入管道的信息。

  • 管道是半双工的,数据只能向一个方向流动;需要双方通信时,需要建立起两个管道
  • 只能用于父子进程或者兄弟进程之间(具有亲缘关系的进程)。比如fork或exec创建的新进程,在使用exec创建新进程时,需要将管道的文件描述符作为参数传递给exec创建的新进程。当父进程与使用fork创建的子进程直接通信时,发送数据的进程关闭读端,接受数据的进程关闭写端。
  • 管道只能在本地计算机中使用,而不可用于网络间的通信。

命名管道(FIFO)

命名管道是一种特殊类型的文件,它在系统中以文件形式存在。这样克服了管道的弊端,他可以允许没有亲缘关系的进程间通信。

共享内存(Share Memory)

共享内存是在多个进程之间共享内存区域的一种进程间的通信方式,由IPC为进程创建的一个特殊地址范围,它将出现在该进程的地址空间中。其他进程可以将同一段共享内存连接到自己的地址空间中。所有进程都可以访问共享内存中的地址,如果一个进程向共享内存中写入了数据,所做的改动将立刻被其他进程看到。

  • 共享内存是IPC最快捷的方式,共享内存方式直接将某段内存段进行映射,多个进程间的共享内存是同一块的物理空间,仅仅映射到各进程的地址不同而已,因此不需要进行复制,可以直接使用此段空间。
  • 共享内存本身并没有同步机制,需要程序员自己控制。

    内存映射(Memory Map)

    内存映射是由一个文件到一块内存的映射,在此之后进程操作文件,就像操作进程空间里的内存地址一样了。

    套接字(Socket)

    套接字机制不但可以单机的不同进程通信,而且使得跨网机器间进程可以通信。
    套接字的创建和使用与管道是有区别的,套接字明确地将客户端与服务器区分开来,可以实现多个客户端连到同一服务器。

Binder

作为Android系统下的一种IPC机制,其本质上与上面罗列出的IPC机制并无本质上的不同,都是作为进程间通信的一种手段。并且在Android系统中也不是只存在Binder这一种进程间通信的方式,在有些地方也使用了Socket。既然Linux已经提供了众多IPC机制,那么Android 为何还要使用Binder作为主要的进程间通信的方式呢,那么当然有他的优点存在。

  • 采用C/S的通信模式。而在linux通信机制中,目前只有socket支持C/S的通信模式,但socket有其劣势,具体参看第二条。
  • 有更好的传输性能。对比于Linux的通信机制,socket:是一个通用接口,导致其传输效率低,开销大;管道和消息队列:因为采用存储转发方式,所以至少需要拷贝2次数据,效率低;共享内存:虽然在传输时没有拷贝数据,但其控制机制复杂(比如跨进程通信时,需获取对方进程的pid,得多种机制协同操作)。
  • 安全性更高。Linux的IPC机制在本身的实现中,并没有安全措施,得依赖上层协议来进行安全控制。而Binder机制的UID/PID是由Binder机制本身在内核空间添加身份标识,安全性高;并且Binder可以建立私有通道,这是linux的通信机制所无法实现的(Linux访问的接入点是开放的)。
  • 对用户来说,通过binder屏蔽了client的调用server的隔阂,client端函数的名字、参数和返回值和server的方法一模一样,对用户来说犹如就在本地(也可以做得不一样),这样的体验或许其他ipc方式也可以实现,但binder出生那天就是为此而生。

Java层Binder

Java层Binder的功能,依赖于Native层Binder来实现,可以认为Java层Binder架构是Native层Binder架构的一个镜像。但是这并不影响我们分析Android Java层Binder的功能。我们用一个例子来说明这个过程。

我们在第一篇中就讲解了SystemServer这个进程,这个进程和zygote进程一起撑起了Android 世界,他们之中有一个崩溃,Android世界就会砰然倒塌。Android许多的重要的系统服务如AMS、PMS等都运行在SystemServer进程中。但是还有一个比较重要的进程ServiceManager进程(简称SM)跟zygote是兄弟进程。这个进程的作用是用来统一管理服务,如AMS。它们之间的关系如下。

我们的AMS需要向SM进程中注册信息,其他进程如果想使用AMS,那么先和ServiceManager进程进行通信查询,接着再和AMS所在SystemServer进程通信。这部分关系图如下

相关文章:

  • 深入理解计算机操作系统(三)
  • GrapeCity Demo示例展示:如何用Spread.Sheets来创建应用|附演示文件下载
  • Glovo完成1.15亿欧元C轮融资,成为欧洲相关技术聚合中心
  • json提取嵌套数据
  • abstract 为什么不能与private,static,final一起使用????
  • springboot2整合OAuth2.0认证实例
  • 关于Vue和React区别的一些笔记
  • [Sdoi2010]地精部落
  • samba服务
  • RabbitMQ中各种消息类型如何处理?
  • 初识 JSP---(servlet / ServletConfig接口 / ServletContext接口)
  • 根据IP查地理位置信息
  • 使用git将代码推到coding
  • 理解在java “”i=i++;”所发生的事情
  • HDU 6342 Expression in Memories(模拟)多校题解
  • JavaScript-如何实现克隆(clone)函数
  • 分享一款快速APP功能测试工具
  • C语言笔记(第一章:C语言编程)
  • IIS 10 PHP CGI 设置 PHP_INI_SCAN_DIR
  • JavaScript-Array类型
  • Less 日常用法
  • Promise面试题,控制异步流程
  • Service Worker
  • Spring Cloud(3) - 服务治理: Spring Cloud Eureka
  • SQLServer插入数据
  • WordPress 获取当前文章下的所有附件/获取指定ID文章的附件(图片、文件、视频)...
  • 第十八天-企业应用架构模式-基本模式
  • 基于Android乐音识别(2)
  • 记一次删除Git记录中的大文件的过程
  • 技术攻略】php设计模式(一):简介及创建型模式
  • 配置 PM2 实现代码自动发布
  • 使用putty远程连接linux
  • 详解NodeJs流之一
  • 赢得Docker挑战最佳实践
  • 06-01 点餐小程序前台界面搭建
  • ​2020 年大前端技术趋势解读
  • ​如何防止网络攻击?
  • #《AI中文版》V3 第 1 章 概述
  • #LLM入门|Prompt#2.3_对查询任务进行分类|意图分析_Classification
  • #免费 苹果M系芯片Macbook电脑MacOS使用Bash脚本写入(读写)NTFS硬盘教程
  • #前后端分离# 头条发布系统
  • #设计模式#4.6 Flyweight(享元) 对象结构型模式
  • (NSDate) 时间 (time )比较
  • (ZT)北大教授朱青生给学生的一封信:大学,更是一个科学的保证
  • (编译到47%失败)to be deleted
  • (附源码)php投票系统 毕业设计 121500
  • (教学思路 C#之类三)方法参数类型(ref、out、parmas)
  • (论文阅读11/100)Fast R-CNN
  • (四)Linux Shell编程——输入输出重定向
  • (转)EXC_BREAKPOINT僵尸错误
  • (转)iOS字体
  • (转)可以带来幸福的一本书
  • .NET 8 中引入新的 IHostedLifecycleService 接口 实现定时任务
  • .NET 应用启用与禁用自动生成绑定重定向 (bindingRedirect),解决不同版本 dll 的依赖问题
  • .pings勒索病毒的威胁:如何应对.pings勒索病毒的突袭?