• 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访问

  • 相关阅读:
    【网络】【操作系统】select、poll、epoll
    【JMM】java内存模型及volatile关键字底层
    【数据库】连接查询(from 内连接 外连接)
    【数据库】SQL牛客练习关键点复习
    【SpringMVC】文件/图片 的下载与上传
    【SpringMVC】拦截器实现与网页跳转步骤
    什么是hashMap,初始长度,高并发死锁,java8 hashMap做的性能提升
    自己写一个HashMap
    String去除重复字符两个方法
    Solr与Elasticsearch比较
  • 原文地址:https://www.cnblogs.com/liusiluandzhangkun/p/9157995.html
Copyright © 2020-2023  润新知