9.12 Binder系统_Java实现_内部机制_Client端

Java实现中client端的RPC层(java实现)如何通过JNI来调用IPC层(C++实现)发送数据

TestServer通过addService向Service_manager注册的时候TestServer是Client端,Service_manager是Server端;

TestClient通过getService向Service_manager请求服务的时候TestClient是Client端,Service_manager是Server端;

TestClient调用RPC层的sayhello或者sayhello_to把请求发送给TestServer,TestClient是Client端,TestServer是Server端;

(1)addService

  getIServiceManager().addService

getService

  getIServiceManager().getService

getIServiceManager()返回的是ServiceManagerProxy对象,对象里的addService 和getService函数都是构造好数据后调用mRemote.transact来发送数据

(2)sayhello和sayhello_to

 也都是构造好数据后使用mRemote.transact来发送数据,这时的mRemote是在IHelloService.Stub.Proxy类中

(3)统一使用mRemote.transact来发送数据,mRemote表示目的,源是函数的调用者,数据保存在transact函数的参数中;

对于addService/getService,其mRemote是一个Java BinderProxy对象,它的mObject指向一个C++的BpBinder对象,这个BpBinder的mHandle=0;

对应sayhello/sayhello_to,其mRemote是一个Java BinderProxy对象,它的mObject指向一个C++的BpBinder对象,这个BpBinder的mHandle=1;这个1来至于getService("hello")

5.1 ServiceManagerProxy中mRemote的构造 (用于addService/getService)
猜测:使用0直接构造出一个java BinderProxy对象

getIServiceManager().addService /getIServiceManager().getService

getIServiceManager()
  return ServiceManagerNative.asInterface(BinderInternal.getContextObject())

a. BinderInternal.getContextObject() // 得到了一个Java BinderProxy对象, 其中mObject指向new BpBinder(0);
getContextObject它是一个JNI调用,对应 android_os_BinderInternal_getContextObject, // android_util_Binder.cpp

android_os_BinderInternal_getContextObject
  sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
                   return   getStrongProxyForHandle(0);
                        b = new BpBinder(handle); // mHandle = 0
  return javaObjectForIBinder(env, b); // b = new BpBinder(0), mHandle = 0

// 使用c代码调用NewObject来创建JAVA BinderProxy对象

javaObjectForIBinder(env, b)
  object = env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor);

  // 设置该对象的mObject = val.get = b = new BpBinder(0)
  env->SetLongField(object, gBinderProxyOffsets.mObject, (jlong)val.get());

  return object;

b. ServiceManagerNative.asInterface
new ServiceManagerProxy(obj); // obj = BinderProxy对象
mRemote = obj = BinderProxy对象, 其中mObject指向new BpBinder(0);

5.2 hello服务里的mRemote如何构造
a. IBinder binder = ServiceManager.getService("hello");
猜测: 它的返回值就是一个java BinderProxy对象, 其中的mObject=new BpBinder(handle)
new ServiceManagerProxy().getService("hello")
....
IBinder binder = reply.readStrongBinder();
nativeReadStrongBinder // Parcel.java

nativeReadStrongBinder是一个JNI调用, 对应的代码是 android_os_Parcel_readStrongBinder
android_os_Parcel_readStrongBinder
// 把java Parce对象转换为c++ Parcel对象
// client程序向sevice_manager发出getService请求,
// 得到一个回复reply, 它里面含有flat_binder_object
// 它被封装成一个c++ Parcel对象
Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);

/* parcel->readStrongBinder()应该是一个 new BpBinder(handle)
* unflatten_binder(ProcessState::self(), *this, &val);
* *out = proc->getStrongProxyForHandle(flat->handle);
* b = new BpBinder(handle);
*/

// 它会创建一个java BinderProxy对象, 其中的mObject=new BpBinder(handle)对象
return javaObjectForIBinder(env, parcel->readStrongBinder());

b. IHelloService svr = IHelloService.Stub.asInterface(binder);
new IHelloService.Stub.Proxy(obj); // obj = 步骤a得到的binder
mRemote = remote;

5.3 现在知道了:mRemote就是一个java BinderProxy 对象
看一下mRemote.transact()
transactNative(code, data, reply, flags);
它是一个JNI调用,对应android_os_BinderProxy_transact

android_os_BinderProxy_transact
// 从java BinderProxy对象中把mObject取出, 它就是一个BpBinder对象
IBinder* target = (IBinder*)env->GetLongField(obj, gBinderProxyOffsets.mObject);

// 然后调用BpBinder的transact
status_t err = target->transact(code, *data, reply, flags);

原文地址:https://www.cnblogs.com/liusiluandzhangkun/p/9157995.html

时间: 2024-11-14 12:48:39

9.12 Binder系统_Java实现_内部机制_Client端的相关文章

9.13 Binder系统_Java实现_内部机制_Server端

logcat TestServer:* TestClient:* HelloService:* *:S &CLASSPATH=/mnt/android_fs/TestServer.jar app_process / TestServer &CLASSPATH=/mnt/android_fs/TestClient.jar app_process / TestClient helloCLASSPATH=/mnt/android_fs/TestClient.jar app_process / T

9.7 Binder系统_c++实现_内部机制1

1. 内部机制_回顾binder框架关键点 binder进程通讯过程情景举例: test_server通过addservice向service_manager注册服务 test_client通过getservice向service_manager获取服务 然后test_client使用服务和test_server通讯 在上述通讯过程中涉及的对驱动访问: (1)注册服务过程add_service a.test_server为每个服务构造一个flat_binder_object结构体,不同服务结构体

Android驱动学习-内部机制_回顾binder框架关键点

内部机制_回顾binder框架关键点server注册服务时, 对每个服务都提供不同的ptr/cookie,在驱动程序里对每个服务都构造一个binder_node, 它也含有ptr/cookie client使用服务前要先getService:会在驱动程序里对该服务构造一个binder_ref, binder_ref含有desc, node成员, desc是整数, node指向对应服务的binder_node 使用服务时, client构造数据,调用ioctl:数据里含有handle 驱动程序根据

黑马程序员_Java基础_接口

------- android培训.java培训.期待与您交流! ---------- 0.接口知识体系 Java接口的知识体系如下图所示,掌握下图中的所有知识就可精通接口. 1.接口概论 1)接口概念 接口是从多个相似类中抽象出来的规范,接口中不包含普通方法,所有方法都是抽象方法,接口不提供实现.接口体现的是规范和实现分离的哲学.规范和实现分离正是接口的好处,让软件系统的各个组件之间面向接口耦合,是一种松耦合的设计.接口定义的是多个类共同的公共行为规范,定义的是一组公用方法. 2)接口与抽象类

Linux嵌入式学习-远程过程调用-Binder系统

Binder系统的C程序使用示例IPC : Inter-Process Communication, 进程间通信RPC : Remote Procedure Call, 远程过程调用 这里我们直接只用android系统中已经实现好的Bindrt系统. 具体源代码在 frameworks\native\cmds\servicemanager\目录下. service_manager.c :a. binder_openb. binder_become_context_managerc. binder

Hadoop2.7.3 多台主机完全分布式搭建(Mac OS X 10.12.4系统 + Parallels Desktop 12 Pro Edition)

Hadoop2.7.3 多台主机完全分布式搭建(Mac OS X 10.12.4系统) 前言 由于学校课程实验的要求,特意需要搭建hadoop的完全分布式系统,所以自己就蛋疼的配了,可惜关于MAC系统的Hadoop搭建材料太少,而且真正的基于校园网的配置基本上没有(基本是在一台电脑上进行,因此当在多台电脑上运行会有许多bug),因此这里想要能够将自己搭的过程想要分享给大家,可能有些配置的解释没有那么全面,所以希望大家见谅?? 环境 基于Mac OSX 10.12.4(Sierra).Ubuntu

Y460 安装ubuntu 12.04系统黑屏,登录界面黑屏

ubuntu 12.04系统黑屏,登录界面黑屏,但是命令行界面可以登录,也可以正常使用,当时在装CVS,装完重启就这样了,可能是因为前一天装更新时,突然断电导致图形界面损坏,参考他人方法,终于修复,总结如下: 1.硬件环境 Intel? Core? i3-2400 CPU @ 3.10GHz × 4 2.显卡 Intel 集成显卡 3.系统版本 ubuntu12.04.2 4.现象 开机后,可以看到grub 菜单,通过grub 菜单进入 ubuntu 12.04,屏幕变黑,屏幕微微亮光,[小光标

Android Binder 系统学习笔记(一)Binder系统的基本使用方法

1.什么是RPC(远程过程调用) Binder系统的目的是实现远程过程调用(RPC),即进程A去调用进程B的某个函数,它是在进程间通信(IPC)的基础上实现的.RPC的一个应用场景如下: A进程想去打开LED,它会去调用led_open,然后调用led_ctl,但是如果A进程并没有权限去打开驱动程序呢? 假设此时有一个进程B由权限去操作LED驱动程序,那么进程A可以通过如下方式来操作LED驱动: ①封装数据,即A进程首先把想要调用的B进程的某个函数的(事先约定好的)代号等信息封装成数据包 ②A进

android数据存储_内部存储

源码下载(免下载积分):下载 你可以直接存储数据到内部存储中,默认情况下,文件存储到内部存储中是私有的,不能被 其他程序访问,当卸载应用程序,这些文件会被移除. 创建并写入数据可以有两种方法: 使用java中的相关的方法, 使用android.content中的相关方法,  调用 openFileOutput(),并返回FileOutputStream对象 调用FileOutputStream对象的write()方法 关闭流 读文件也是基本相同的方式. 在读文件有一点小技巧:如果想在编译时保存一