今天这篇文章是通过看源码的方式做总结:

  • 从客户端的应用层到binder驱动,然后从binder驱动在到服务端的应用层
  • Binder的协议通信流程

Binder完整的IPC通信流程——源码分析

还是根据这幅图,我们来看下源码,从客户端到服务端的流程:

1、客户端Proxy调用fromwork的是java层BinderProxy

Binder完整的IPC通信流程——源码分析

2、fromwork的是java层BinderProxy调用 native的Bpbinder

Binder完整的IPC通信流程——源码分析

3、native的Bpbinder调用IPCThreadState的transact

Binder完整的IPC通信流程——源码分析

3.1Pracel数据转换成Binder识别的数据,Binder_transactionBinder完整的IPC通信流程——源码分析

3.2 先在驱动里面写数 ,然后通过驱动的回复标记,处理操作,收到REPLY后,在mIn中读出来转成Parcle返回回去

Binder完整的IPC通信流程——源码分析

3.3由此可以看出,最终与驱动的数据是binder_write_read 不是parcel 不是binder_transaction,最终调用iocl写出去。但是注意代码看出,写的优先级 高于读的优先级

Binder完整的IPC通信流程——源码分析
Binder完整的IPC通信流程——源码分析


至此 客户端的操作看完了,我们接着看下服务端的操作

Binder完整的IPC通信流程——源码分析
Binder完整的IPC通信流程——源码分析
Binder完整的IPC通信流程——源码分析

继续看BBinder怎么传到java层的

Binder完整的IPC通信流程——源码分析
Binder完整的IPC通信流程——源码分析
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200426183916429.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8zOTA3OTA0OA==,size_16,color_FFFFFF,t_70

Binder完整的IPC通信流程——源码分析


下图是Binder相关的协议流程图:
1、Client端向发起IPC指令BC_TRANSACTION,驱动收到返回BR_TRANSACTION_COMPLETE
2、然后驱动向Server端传递BR_TRANSACTION,Server端收到后,进行处理,然后通知Binder驱动已经返回,驱动完成后,回复BR_TRANSACTION_COMPLETE,然后驱动在返回客户端指令BR_REPLY。至此整个流程结束
Binder完整的IPC通信流程——源码分析

总结:

客户端流程:

1.客户端的Proxy(java层服务的代理)调用transact()
2.调用Framwork层的binderProxy 的tranceNative()
3.然后通过Parcel转换成BpBinder,再次transact()
4.此时会调用IPCThreadState的tansact(), 注意和驱动打交道的是IPCThreadState,不是BinderProxy,也不是BpBinder。

  • 着重介绍一个IPCThreadState的tansact方法第一个参数mHandle:和Binder驱动交互的时候,只传mHandler,驱动和mHandle知道对应的binder引用,也就会找到对应的binder实例

5.IPCThreadState的tansact, 注意:IPCThreadState中由两个引用mOut: 我们在驱动写东西的时候,先这里面。 mIn:我们在驱动中读数据的时候, 先读到mIn中

  • a.第一件事:是先把java层的数据转换数据格式parcel转换成binder_transaction.
  • b.第二件事:在一个循环中,先与驱动交互把数据写出去,然后不断接收驱动指令。(这里注意最终和Binder数据格式事binder_write_read,不是parcel也不是binder_transaction)
  • BC_TRANSACTION: 表示驱动已经接收到客户端的请求了
  • BC_REPLY: 表示服务端已经接收到请求,可以退出了
  • c.收到BC_REPLY指令后,从mIn中binder_trancasion在转成Parcle,返回上层

服务端流程:

1、new 一个普通线程,然后传入Binder驱动,成为binder线程池

  • BC_ENTER_LOOPER : 表示这个线程主动注册到Binder驱动
  • BC_REGISTER_LOOPER: 被动处理,由Binder驱动先申请,然后应用再来注册

2、进入循环里面操作

  • a、从驱动中取数据(mIn中取出来转成对应的数据格式)
  • b、从mIn中不断的读取指令,进入case操作。(根据不同指令,走不通的case,流程:client请求发给驱动,驱动发给Server,Server的binder线程中就会收到这个指令)
  • c、case中接收指令BR_TRANSACTION,读出数据转成parcel转给上层(java层)
  • d、传到上层以后,往驱动写一跳数据指令为BC_REPLY,客户端接收到这个标记以后,就可以退出返回了,然后我们发送请求的时候waitForResponse(null,null), 表示不用等待请求返回结果

3、BBinder怎么传到java层的?

  • a、在native通过JNI调用,调用Binder对象的onTransact()方法。 Binder对象就是AIDL生成的Stub类
  • b、调用本地函数publishBinder,调用本地函数,把binder存起来

4、解释一下asInterface(): 先从客户端发过来的数据中把binder读出来,然后在转化成业务接口的对象,Binder到server端就binderProxy了

相关文章:

  • 2021-04-27
  • 2022-12-23
  • 2021-05-01
  • 2021-12-19
  • 2021-12-12
  • 2021-10-01
猜你喜欢
  • 2021-04-09
  • 2021-10-29
  • 2021-10-23
  • 2022-12-23
  • 2021-03-31
  • 2022-12-23
  • 2021-06-01
相关资源
相似解决方案