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 在TestClient中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()应该根据flat_binder_object返回一个 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);

怎么发:

对于getService/addService,会得到一个ServiceManagerProxy代理类;

对于hello服务,也会得到一个代理类IHelloService.Stub.Proxy

这些代理类中都有一个mRemote成员,它是一个Java BInderProxy,它的mObject成员指向一个C++ BpBinder对象,BpBinder中有一个mHandle,对于addService和getService的mHandle为0,表示发给ServiceManager,对于hello服务,mHandle的值来自getService的结果

发送数据时,调用mRemote.transact,它会从mObject中取出Bpbinder对象,调用它的transact函数,实现了Java写的RPC层对C++写的IPC层通过ioctl访问

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

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

    logcat TestServer:* TestClient:* HelloService:* *:S &CLASSPATH=/mnt/android_fs/TestServer.jar ap ...

  2. 9.8 Binder系统_c++实现_内部机制1

    1. 内部机制_回顾binder框架关键点 binder进程通讯过程情景举例: test_server通过addservice向service_manager注册服务 test_client通过get ...

  3. 9.10 Binder系统_Java实现_hello服务

    怎么做?2.1 定义接口: 写IHelloService.aidl文件, 上传, 编译, 得到IHelloService.java 里面有Stub : onTransact, 它会分辨收到数据然后调用 ...

  4. 9.9 Binder系统_Java实现_Android里java程序的编译启动

    如果知道了进程号:通过ls /proc/进程号/task 可以看到所有线程    cat /proc/进程号/task/线程号/comm  可以达到线程名字(主线程是main,主线程号就是进程号) d ...

  5. 9.7 Binder系统_c++实现_编写程序

    参考文件:frameworks\av\include\media\IMediaPlayerService.h (IMediaPlayerService,BnMediaPlayerService)fra ...

  6. 9.2 Binder系统_驱动情景分析_服务注册过程

    1. 几个重要结构体的引入给test_server添加一个goodbye服务, 由此引入以下概念: 进程间通信其实质也是需要三要素:源.目的.数据,源是自己,目的用handle表示:通讯的过程是源向实 ...

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

    内部机制_回顾binder框架关键点server注册服务时, 对每个服务都提供不同的ptr/cookie,在驱动程序里对每个服务都构造一个binder_node, 它也含有ptr/cookie cli ...

  8. 9.11 Binder系统_分层

    1.Binder系统过程分析,情景分析 server提供服务 (1)addService(服务名称,xxx)执行后会导致binder驱动在server的内核空间为服务创建一个binder_node结构 ...

  9. 012_STM32程序移植之_内部flash开机次数管理lib库建立

    012_STM32程序移植之_内部flash开机次数管理lib库建立 1. 测试环境:STM32C8T6 2. 测试接口: 3. 串口使用串口一,波特率9600 单片机引脚------------CH ...

随机推荐

  1. 使用QML自绘页面导航条

    使用QML自绘页面导航条 近期使用QML制作项目,依照要求.须要制作成分页的插件.遗憾的是,QML的控件库Qt Quick都没有现成的控件,于是我尝试着自己实现自绘页面导航条. 原创文章,反对未声明的 ...

  2. Android Retrofit+RxJava 优雅的处理服务器返回异常、错误

    标签: 开始本博客之前,请先阅读: Retrofit请求数据对错误以及网络异常的处理 异常&错误 实际开发经常有这种情况,比如登录请求,接口返回的 信息包括请求返回的状态:失败还是成功,错误码 ...

  3. J2msi 自己制作的把exe打成安装包简易GUI程序

    因为wix是用命令行执行的,操作比较麻烦,所以自己写了个wix生成安装包的图形操作程序, 原理很简单,主要用java 来执行 wix 的heat .candle 和 light 命令 ,最后生成安装文 ...

  4. 微信小程序,前端大梦想(二)

    微信小程序之数据缓存实例-备忘录     数据缓存在移动端的使用是非常重要的,既可以减少用户的流量支出又可以提高程序的访问速度和用户体验.每个微信小程序都可以有自己的本地缓存,可以通过 wx.setS ...

  5. 【习题 8-12 UVA - 1153】Keep the Customer Satisfied

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 结束时间比较早的,就早点开始做. 所以,将n件事情,按照结束时间升序排. 然后对于第i件事情. 尽量把它往左排. 即t+1..t+a ...

  6. GCC中-fpic解惑(转载)

    参考: 1.<3.18 Options for Code Generation Conventions>2.<Options for Linking>3.<GCC -fP ...

  7. STL_算法_查找算法(search、find_end)

    C++ Primer 学习中. .. 简单记录下我的学习过程 (代码为主) search          //从左往右找第一个符合条件的子区间    全部容器适用 find_end  //从右往左找 ...

  8. 【D3 API 中文手冊】

    [D3 API 中文手冊] 声明:本文仅供学习所用,未经作者同意严禁转载和演绎 <D3 API 中文手冊>是D3官方API文档的中文翻译. 始于2014-3-23日,基于VisualCre ...

  9. Android-CheckBox 实现计算器

    源码下载地址:http://download.csdn.net/detail/wu20093346/7718055 使用CheckBox的OnCheckedChangeListener做事件触发,效果 ...

  10. 分析深圳电信的新型HTTP劫持方式

    昨天深圳下了一天的暴雨,2014年的雨水真是够多的. 用户的资源就是金钱,怎的也要好好利用嘛不是? ISP的劫持手段真是花样百出.从曾经的DNS(污染)劫持到后来的共享检測.无不通过劫持正常的请求来达 ...