Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >[084]Binder答疑解惑(二)

[084]Binder答疑解惑(二)

作者头像
王小二
发布于 2023-09-11 06:09:03
发布于 2023-09-11 06:09:03
27800
代码可运行
举报
运行总次数:0
代码可运行

问题

能否深入讲解一下Binder中的序列化

一、什么是序列化

我们先来百度一下,百度的结果

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
序列化 (Serialization)是将对象的状态[信息转换]为可以存储或传输的形式的过程。
在序列化期间,对象将其当前状态写入到临时或[持久性]存储区。
以后,可以通过从存储区中读取或反序列化对象的状态,重新创建该对象。

举个例子,这个对象如何序列化。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Person {
    String name;
    int age;
}

只需要序列化的时候将String和int写个某个内存区域,反序列化的时候读取这个内存区域,重新构造一个Person对象。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Person implements Parcelable {
    String name;
    int age;

    public static final Parcelable.Creator CREATOR = new Creator() {
        @Override
        public Object createFromParcel(Parcel parcel) {
            Person person = new Person();
            person.name = parcel.readString();
            person.age = parcel.readInt();
            return person ;
        }

        @Override
        public Object[] newArray(int i) {
            return new Object[0];
        }
    };

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(@NonNull Parcel parcel, int i) {
        parcel.writeString(name);
        parcel.writeInt(age);
    }

}

Parcelable就是按照这个意思实现基础数据类型的。

这块内存区域就是Parcel对象对应的内存区域。

writeToParcel就是序列化,代码的内部实现就会将name和age按照规则写到parcel中

createFromParcel就是反序列化,代码的内部实现就会从Parcel中读取name和age,然后重新构造Person类。

难道Binder的序列化就这么简单,当然还没有,Binder考虑的更多。

二、序列化后是同一个对象吗?

当然可以很明显的看到序列化后就不是一个对象。你操作反序列之后对象,其实在操作一个新的对象,和原始对象没有关系。

Binder的目标就是让对象在经过Binder接口传递之后,反序列化后的对象用起来和原始对象一样。

对Person类进行扩展,加入一个IBinder对象和一个File。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Person {
    String name;
    int age;
    IBinder action;//Binder对象
    File  file;//sdcard/1.txt
}

经过Binder的传递这个对象之后,对端将会拿到一个对象

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Person {
    String name;
    int age;
    IBinder action;//BinderProxy对象
    File  file;//sdcard/1.txt
}

IBinder的对象从Binder对象变成BinderProxy对象,File对象变成了新的File都指向了同一个文件。

我们在来好好理解一下这段话:反序列化后的对象用起来和原始对象一样。

2.1 IBinder用起来是不是和原始的IBinder一样

当左边的进程调用Binder.transact最后调用的是Binder.onTransact

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    public final boolean transact(int code, @NonNull Parcel data, @Nullable Parcel reply,
            int flags) throws RemoteException {
        if (false) Log.v("Binder", "Transact: " + code + " to " + this);

        if (data != null) {
            data.setDataPosition(0);
        }
        boolean r = onTransact(code, data, reply, flags);
        if (reply != null) {
            reply.setDataPosition(0);
        }
        return r;
    }

当右边的进程调用BinderProxy的transact接口会通过Binder驱动跨进程调用Binder.onTransact。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    //Entry point from android_util_Binder.cpp's onTransact.
    @UnsupportedAppUsage
    private boolean execTransact(int code, long dataObj, long replyObj,
            int flags) {
            return execTransactInternal(code, dataObj, replyObj, flags, callingUid);
    }

    private boolean execTransactInternal(int code, long dataObj, long replyObj, int flags,
            int callingUid) {
            res = onTransact(code, data, reply, flags);
        return res;
    }

因为BinderProxy和Binder都实现了IBinder接口,都实现了transact接口,所以将BinderProxy.transact和Binder.transact来说两者的效果是一样的。

思考 如果把右边的对象再传递给左边的进程,会发生什么,IBinder对象是Binder还是BinderProxy 答案:https://cloud.tencent.com/developer/article/1639790

2.2 File用起来是不是和原始的File一样

这个部分我就不另外将了,可以参考我的另外一篇文章,https://cloud.tencent.com/developer/article/1639804,直接说结论。

经过Binder传递的File指向内核中同一file结构体,所以右边进程读写File和左边进程读写File是一样。

需要注意的是如果用ParcelFileDescriptor,因为在传递File之前重新打开了一次File,这样子虽然操作的是同一个文件,可能无法共享读写指针了。

三、Binder作出的努力

Binder为以下的对象类型实现了跨进程传递,但是本质上只实现了Binder对象,BinderProxy对象,和FD的传递,配合上IBinder对象的跨进程调用和Linux的一切皆文件的设计理念,基本达成了Parcelable对象在经过Binder接口传递后,用起来和原始的对象一样目标。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    enum {
        BINDER_TYPE_BINDER = B_PACK_CHARS('s', 'b', '*', B_TYPE_LARGE),//Binder
        BINDER_TYPE_WEAK_BINDER = B_PACK_CHARS('w', 'b', '*', B_TYPE_LARGE),//Binder
        BINDER_TYPE_HANDLE = B_PACK_CHARS('s', 'h', '*', B_TYPE_LARGE),//BinderProxy
        BINDER_TYPE_WEAK_HANDLE = B_PACK_CHARS('w', 'h', '*', B_TYPE_LARGE),//BinderProxy
        BINDER_TYPE_FD = B_PACK_CHARS('f', 'd', '*', B_TYPE_LARGE),//文件fd
        BINDER_TYPE_FDA = B_PACK_CHARS('f', 'd', 'a', B_TYPE_LARGE),//文件fd数组,但是似乎没看到用的地方
        BINDER_TYPE_PTR = B_PACK_CHARS('p', 't', '*', B_TYPE_LARGE),//这是什么类型,留一个思考题
      };

思考题 BINDER_TYPE_PTR目前只支持在hwbinder中,看看他的本质是什么,是否实现用起来和原始对象一样。 需要查看的代码 system/libhwbinder/Parcel.cpp中的writeBuffer common/drivers/android/binder.c中case BINDER_TYPE_PTR的处理

总结

如果你想要真正了解Binder的序列化只需要去研究parcel.cpp和binder.c,整个步骤分成三步:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
第一步:客户端使用parcel.cpp提供接口负责将对象A打包成binder驱动可以识别格式,并传递给Binder驱动
第二步:binder驱动按照自己支持的能力,将对象转化成对服务端可以访问的区域以及parcel.cpp可以识别的格式
第三步:服务端使用parcel.cpp提供接口将驱动传递过来的数据重新解析对象A`。

任何序列化和反序列化的机制,让我去研究,我都按照反序列化后的对象用起来和原始对象一样。要求去研究,然后去探究对应的跨进程,跨芯片通信机制是如何实现这个目标的。

尾巴

去了解设计者的设计理念和设计目标,有助于你真正的透过现象看到本质。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-09-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
[089]图解Binder应用篇-补课篇
今天完成了 王小二图解Android【010】Binder应用篇的直播,说实话这次我只能给自己打一个59分数。回去我在不断思考,最后觉得这个Binder培训就根本不应该采用1对多的培训模式,其实我在昨晚就给一个毕业半年左右的网友一对一的试讲过,中途我们会不断地交流,给他补了很多知识,最后效果我觉得有85分。 但是今天一整天我一直心有不甘,我觉得还是有必要为自己今天的直播课上一个补课。
王小二
2023/11/20
2880
[089]图解Binder应用篇-补课篇
Android跨进程通信IPC之10——Binder之Framework层Java篇
Binder在framework层,采用JNI技术来调用native(C/C++)层的binder架构,从而为上层应用程序提供服务。看过binder之前的文章,我们知道native层中,binder是C/S架构,分为Bn端(Server)和Bp端(Client)。对于Java层在命令与架构上非常相近,同时实现了一套IPC通信架构。
隔壁老李头
2018/08/30
2.1K0
Android跨进程通信IPC之10——Binder之Framework层Java篇
【Binder 机制】AIDL 分析 ( 分析 AIDL 文件生成的 Java 源文件 | Binder | IBinder | Stub | Proxy )
在上一篇博客 【Binder 机制】AIDL 分析 ( 创建 AIDL 文件 | 创建 Parcelable 类 | AIDL 中使用 Parcelable 类 | 编译工程生成 AIDL 对应的Java源文件 ) 创建了 AIDL 文件 , 并编译生成了 AIDL 文件对应的 Java 源文件 , 现在开始分析生成在 " AIDL_Demo\app\build\generated\aidl_source_output_dir\debug\out\kim\hsl\aidl_demo " 目录 中的 " IMyAidlInterface.java " 源文件 ;
韩曙亮
2023/03/29
1.8K0
Android开发之漫漫长途 Ⅷ——Android Binder(也许是最容易理解的)
该文章是一个系列文章,是本人在Android开发的漫漫长途上的一点感想和记录,我会尽量按照先易后难的顺序进行编写该系列。该系列引用了《Android开发艺术探索》以及《深入理解Android 卷Ⅰ,Ⅱ,Ⅲ》中的相关知识,另外也借鉴了其他的优质博客,在此向各位大神表示感谢,膜拜!!!另外,本系列文章知识可能需要有一定Android开发基础和项目经验的同学才能更好理解,也就是说该系列文章面向的是Android中高级开发工程师。
LoveWFan
2018/08/07
6820
Android开发之漫漫长途 Ⅷ——Android Binder(也许是最容易理解的)
跨进程通信(socket,binder,handler),Binder ,linkToDeathAIDL,Bundle,使用Socket
(1)IPC是Inter-Process Communication的缩写,含义为进程间通信或者跨进程通信,是指两个进程之间进行数据交换的过程。 (2)ANR是Application Not Responding的缩写,即应用无响应。主线程执行大量的耗时操作容易导致ANR现象发生。5s,广播10s (3)在Android中最有特色的进程间通信方式就是Binder了,通过Binder可以轻松地实现进程间通信。 (4)Android还支持Socket,通过Socket也可以实现任意两个终端或者两个进程之间的通信。
zhangjiqun
2024/12/16
6220
跨进程通信(socket,binder,handler),Binder ,linkToDeathAIDL,Bundle,使用Socket
图解 | Binder浅析(一)
Framework和Binder的内容挺深的,本文还是站在应用层开发者的角度来建立基本认知,能在遇到问题的时候有思路和方向即可。(本文将带着关键问题和核心流程展开,不会面面俱到)
Holiday
2020/11/06
9710
Binder 进程通信
对应一个4GB的虚拟地址空间,其中3GB是用户空间,1GB是内核空间,当然内核空间的大小是可以通过参数配置调整的。对于用户空间,不同进程之间彼此是不能共享的,而内核空间却是可共享的。Client进程向Server进程通信,恰恰是利用进程间可共享的内核内存空间来完成底层通信工作的,Client端与Server端进程往往采用ioctl等方法跟内核空间的驱动进行交互。
Yif
2019/12/26
8860
听说你Binder机制学的不错,来面试下这几个问题(三)
很多文章将Binder框架定义了四个角色:Server,Client,ServiceManager、以及Binder驱动,但这容易将人引导到歧途:好像所有的Binder服务都需要去ServiceManager去注册才能使用,其实不是这样。例如,平时APP开发通过bindService启动的服务,以及有些自己定义的AIDL远程调用,都不一定都ServiceManager注册这条路,个人理解:ServiceManager主要功能是:管理系统服务,比如AMS、WMS、PKMS服务等,而APP通过的bindService启动的Binder服务其实是由SystemServer的ActivityManagerService负责管理。这篇主要关注Android APP Java层Binder通信一些奇葩点:
看书的小蜗牛
2018/06/29
2K0
听说你Binder机制学的不错,来面试下这几个问题(三)
我也想聊聊Binder机制
想写篇关于Binder的文章,可对其一无所知,无从下手。在阅读了大量的优秀文章后,心惊胆战的提笔,不怕文章被贻笑大方,怕的是误人子弟!望各位大佬抽空阅读本文的同时,能够对文章的知识点持怀疑态度,共同探讨,共同进步!
Rouse
2019/07/17
8330
我也想聊聊Binder机制
笔记——IPC跨进程通信(九)
进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位。 线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。 (1)线程是进程的一部分 (2)CPU调度的是线程 (3)系统为进程分配资源,不对线程分配资源
木溪bo
2018/12/27
6500
Android Binder 机制——AIDL 的使用和原理分析
为了便于理解,这里用一个 Demo 来展示 AIDL 的实现过程:Activity 作为 Client 与作为 Server 端的远程 Service 实现数据交互,在绑定远程 Service 之后,点击 AddUser 后 Service 会将 Client 端传进来的 User 对象加入列表中,点击 GetSize 后远程 Service 将会把列表的长度返回给客户端。建议在继续阅读之前先查看或者运行一下项目源码:
没关系再继续努力
2021/12/01
7620
借助 AIDL 理解 Android Binder 机制——AIDL 的使用和原理分析
在上一篇文章——借助 AIDL 理解 Android Binder 机制——Binder 来龙去脉[1]中我们已经分析了使用 Binder 机制的原因以及分析了 Binder 机制,本章我们将继续从 AIDL 的使用过程体验 Binder 在应用层的使用和原理。
程序亦非猿
2020/04/15
1K0
借助 AIDL 理解 Android Binder 机制——AIDL 的使用和原理分析
笔记:Binder通信机制
用户1172465
2018/01/08
1.4K0
Android 反序列化漏洞攻防史话
Java 在历史上出现过许多反序列化的漏洞,但大部分出自 J2EE 的组件。即便是 FastJSON 这种漏洞,似乎也很少看到在 Android 中被实际的触发和利用。本文即为对历史上曾出现过的 Android Java 反序列化漏洞的分析和研究记录。
evilpan
2023/03/27
1.9K0
Android 反序列化漏洞攻防史话
Android开发之漫漫长途 IX——彻底掌握Binder
该文章是一个系列文章,是本人在Android开发的漫漫长途上的一点感想和记录,我会尽量按照先易后难的顺序进行编写该系列。该系列引用了《Android开发艺术探索》以及《深入理解Android 卷Ⅰ,Ⅱ,Ⅲ》中的相关知识,另外也借鉴了其他的优质博客,在此向各位大神表示感谢,膜拜!!!另外,本系列文章知识可能需要有一定Android开发基础和项目经验的同学才能更好理解,也就是说该系列文章面向的是Android中高级开发工程师。
LoveWFan
2018/08/07
5580
Android开发之漫漫长途 IX——彻底掌握Binder
Binder进程间通信详解
前言 隔行如隔山,这句话同样适用于任何时候,即时同一个专业,深入下去的话,差别也是巨大的。今天,讲下自己如何学习binder进程间通信的机制的一些见解。开始的时候,只知道 Binder 是个很底层的东西,甚至对于具体是什么用都不是很清楚。 主要是通过两种方式: 看别人写的Binder博文 目的很简单,大概了解Binder是个什么东西,有哪些核心的东西,对于看源码的时候选择性过滤有帮助,最好是看了后画下思维导图总结下或者可以画下流程图。 看Binder源码 对于切入点的话,从最熟悉的客户端入手;选择
用户1148881
2018/05/28
1.3K0
Android跨进程通信IPC之5——Binder的三大接口
本片文章的主要目的是让大家对Binder有个初步的了解,既然是初步了解,肯定所是以源码上的注释为主,让大家对Binder有一个更直观的认识。PS:大部分注释我是写在类里面了, 重要的我会单独的拿出来。 主要内容如下:
隔壁老李头
2018/08/30
1.5K0
Android跨进程通信IPC之5——Binder的三大接口
一步步深入解析AIDL
在 Android 系统中,进程间通信 (IPC) 是一种很重要的机制。IPC 产生的原因是某些情况下需要在两个进程之间进行一些数据的交换。而在深入学习 Android 的过程中难免会遇到 IPC 的相关问题,比如常见的有在自己的应用程序中读取手机联系人的信息,这就涉及到 IPC 了。因为自己的应用程序是一个进程,通讯录也是一个进程,只不过获取通讯录的数据信息是通过 Content Provider 的方式来实现的。
俞其荣
2022/07/28
6690
一步步深入解析AIDL
BInder机制总结
首先,Android利用Binder进行通信的话,肯定要首先获取Binder对象。
全栈程序员站长
2022/09/06
6610
Android跨进程通信IPC之4——AndroidIPC基础1
这里强烈建议把前面两篇文章看一遍,因为前面两篇文章对后面大家对android的IPC的理解帮助很大,本片文章主要内容如下
隔壁老李头
2018/08/30
1.3K0
Android跨进程通信IPC之4——AndroidIPC基础1
推荐阅读
相关推荐
[089]图解Binder应用篇-补课篇
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验