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

Posted 拉风摊主

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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);




















































以上是关于9.12 Binder系统_Java实现_内部机制_Client端的主要内容,如果未能解决你的问题,请参考以下文章

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

9.5 Binder系统_驱动情景分析_transaction_stack机制

IPC_Binder_java_1

Android 跨进程通信-Binder机制之ServiceManager对系统Service的管理

红茶一杯话Binder(传输机制篇_上)

红茶一杯话Binder (传输机制篇_下)