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 在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端的更多相关文章
- 9.13 Binder系统_Java实现_内部机制_Server端
logcat TestServer:* TestClient:* HelloService:* *:S &CLASSPATH=/mnt/android_fs/TestServer.jar ap ...
- 9.8 Binder系统_c++实现_内部机制1
1. 内部机制_回顾binder框架关键点 binder进程通讯过程情景举例: test_server通过addservice向service_manager注册服务 test_client通过get ...
- 9.10 Binder系统_Java实现_hello服务
怎么做?2.1 定义接口: 写IHelloService.aidl文件, 上传, 编译, 得到IHelloService.java 里面有Stub : onTransact, 它会分辨收到数据然后调用 ...
- 9.9 Binder系统_Java实现_Android里java程序的编译启动
如果知道了进程号:通过ls /proc/进程号/task 可以看到所有线程 cat /proc/进程号/task/线程号/comm 可以达到线程名字(主线程是main,主线程号就是进程号) d ...
- 9.7 Binder系统_c++实现_编写程序
参考文件:frameworks\av\include\media\IMediaPlayerService.h (IMediaPlayerService,BnMediaPlayerService)fra ...
- 9.2 Binder系统_驱动情景分析_服务注册过程
1. 几个重要结构体的引入给test_server添加一个goodbye服务, 由此引入以下概念: 进程间通信其实质也是需要三要素:源.目的.数据,源是自己,目的用handle表示:通讯的过程是源向实 ...
- Android驱动学习-内部机制_回顾binder框架关键点
内部机制_回顾binder框架关键点server注册服务时, 对每个服务都提供不同的ptr/cookie,在驱动程序里对每个服务都构造一个binder_node, 它也含有ptr/cookie cli ...
- 9.11 Binder系统_分层
1.Binder系统过程分析,情景分析 server提供服务 (1)addService(服务名称,xxx)执行后会导致binder驱动在server的内核空间为服务创建一个binder_node结构 ...
- 012_STM32程序移植之_内部flash开机次数管理lib库建立
012_STM32程序移植之_内部flash开机次数管理lib库建立 1. 测试环境:STM32C8T6 2. 测试接口: 3. 串口使用串口一,波特率9600 单片机引脚------------CH ...
随机推荐
- Springboot优化
https://www.cnblogs.com/chen110xi/p/6198481.html
- 64。node.js 中间件express-session使用详解
转自:http://jinjiakarl.com/2018/06/09/node-js-%E4%B8%AD%E9%97%B4%E4%BB%B6express-session%E4%BD%BF%E7%9 ...
- 【深入篇】Android常用布局方式简介
LinearLayout 线性布局是程序中最常见的布局方式.一般分为水平线性布局和竖直线性布局,通过android.orientation属性可以设置线性布局的方向. 在布局中操作颜色时,要用的是十六 ...
- C++里面virtual函数及虚表大小
实验了下面的函数: #include <vector> #include <iostream> using namespace std; class A { public: v ...
- Oracle 10g 10.2.0.1 在Oracle Linux 5.4 32Bit RAC安装手冊(一抹曦阳)
Oracle 10g 10.2.0.1 在Oracle Linux 5.4 32Bit RAC安装手冊(一抹曦阳).pdf下载地址 ,step by step http://download.csdn ...
- windows 2016 配置 VNC 服务
windows 2016 配置 VNC 服务 下载windows版 https://www.realvnc.com/download/vnc/ 安装时勾选 vncserver 进入 "C:\ ...
- 修改android的wifi客户端名称的两种方法
修改android的wifi客户端名称的两种方法 手机连接到无线路由时,在dhcp的客户端列表里面是这样的名称"android-89425253e5de3a2",这就是安卓 ...
- Android学习笔记进阶17之LinearGradient
具体的看一下博文:Android学习笔记进阶15之Shader渲染 package xiaosi.BitmapShader; import android.app.Activity; import a ...
- mahout历史(二)
mahout历史 Apache Mahout起源于2008年,经过两年的发展,2010年4月ApacheMahout最终成为了Apache的顶级项目.Mahout 项目是由 ApacheLucene( ...
- QT常用代码之加载动态库和弹出对话框
作者:朱金灿 来源:http://blog.csdn.net/clever101 加载动态库的代码: typedef void (*Execute)(); // 定义导出函数类型 QString st ...