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 ...
随机推荐
- git 版本管理工具说明
$ git init (初始化本地仓库,会生成.git 文件夹 .git 文件夹里存储了所有的版本信息.标记等内容) $ git add . ...
- C/C++(指针数组)
指针数组 指针数组的本质是数组,数组指针的本质是指针 一个数组中的各个元素都是字符指针,即为字符指针数组,或者指针数组. int arr[] = {1,2,23,45,6};//整形数组 char c ...
- 前端js中this指向及改变this指向的方法
js中this指向是一个难点,花了很长时间来整理和学习相关的知识点. 一. this this是JS中的关键字, 它始终指向了一个对象, this是一个指针; 参考博文: JavaScript函数中的 ...
- vue2细节变化的用法
1.v-el和v-ref合并为一个属性:ref 原来:v-el:my-element 现在: ref="myElement", v-ref:my-component 变成了这样: ...
- 开始刷SGU
计划一天3题 请监督我 谢谢
- 让checkbox不选中
今天在做项目的时候.遇到一个问题.须要把选中的checkbox置空,即将选中的checkbox不选中. 最后,发现一个方法非常好使,特此记录. $("input[type='checkbox ...
- (二十二)unity4.6学习Ugui中文文档-------交互-Eventsystem & Binding
大家好,我是孙广东. 转载请注明出处:http://write.blog.csdn.net/postedit/38922399 更全的内容请看我的游戏蛮牛地址:http://www.unityma ...
- Android自定义视图
Android框架为我们提供了大量的视图类来帮助我们做好展示信息以及同用户进行交互的工作.然后有时候,我们的app或许需要一些在Android内建视图之外特殊的视图,那么此时我们就需要自定义视图.下面 ...
- 欧洲的VPS 1天内收到几万次ssh端口访问,99%的访问量来自中国
欧洲的VPS 1天内收到几万次ssh端口访问,99%的访问量来自中国 前几天开了个欧洲的VPS,当备用的,没怎么用.就这样的VPS在1天之内也收到不少来自中国网民的见面礼 用了别人的一条命令: gre ...
- ubuntu-查看iso文件的md5
直接使用命令md5sum +文件名就可以了.例如 md5sum ~/YLMF_GHOSTWIN7SP1_X86_YN2015.iso 执行结果如下 cdbb7fdc8bbc30e5e0a398f71b ...