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

logcat TestServer:* TestClient:* HelloService:* *:S &
CLASSPATH=/mnt/android_fs/TestServer.jar app_process / TestServer &
CLASSPATH=/mnt/android_fs/TestClient.jar app_process / TestClient hello
CLASSPATH=/mnt/android_fs/TestClient.jar app_process / TestClient hello weidongshan

app_process: frameworks\base\cmds\app_process\app_main.cpp

6.1 server如何读取数据
使用app_process来启动server进程,
它会先创建子线程:
AppRuntime::onStarted()
  proc->startThreadPool();
      spawnPooledThread(true);
        sp<Thread> t = new PoolThread(isMain);
        t->run(name.string());
          // 它会创建子线程, 并执行threadLoop
          IPCThreadState::self()->joinThreadPool(mIsMain);
          {
            do {
              result = getAndExecuteCommand();
              result = talkWithDriver();
              result = executeCommand(cmd);
              对于BR_TRANSACTION数据,
              sp<BBinder> b((BBinder*)tr.cookie);
              error = b->transact(tr.code, buffer, &reply, tr.flags);
              } while(...)
           }

6.2 server读到数据后怎么调用服务PRC层的onTransact函数
a. 在addService时设置.ptr/.cookie
ServiceManager.addService("hello", new HelloService());
分析:
a.1 new HelloService()是JAVA对象
a.2 处理数据时把.cookie转换成BBinder对象, 它是c++对象
所以: addService中肯定会把JAVA对象转换成一个BBinder派生类对象,存在.cookie里

结论:
a.1 addService会通过JNI调用c++函数:
  创建一个BBinder派生类JavaBBinder对象,
    它的.mObject指向JAVA对象: new HelloService()
    它含有onTransact函数
  把这个对象存入.cookie(最终存入binder驱动中该服务对应的binder_node.cookie)

a.2 server进程从驱动中读到数据,里面含有.cookie
  把它转换为BBinder对象,
  调用它的transact函数
  它会调用到派生类JavaBBinder中定义的onTransact函数

a.3 JavaBBinder中定义的onTransact函数(c++)
  它通过JNI调用java Binder的execTransact方法,
  然后调用Binder派生类IHelloService.Stub中定义的onTransact函数(JAVA)

a.4 IHelloService.Stub中定义的onTransact函数(JAVA):
  分析数据
  调用sayhello/sayhello_to

源码阅读:
a.1 ServiceManager.addService("hello", new HelloService());
    ServiceManagerProxy.addService:
      // Parcel.java
      data.writeStrongBinder(service);
        nativeWriteStrongBinder(mNativePtr, val); // val = service = new HelloService()
        它是一个JNI调用,对应android_os_Parcel_writeStrongBinder(c++)

a.2 android_os_Parcel_writeStrongBinder(c++)
  它会构造一个JavaBBinder对象(c++),.mObject=new HelloService() JAVA对象
  然后让.cookie=JavaBBinder对象(c++)
  // 把Java Parcel转换为c++ Parcel
  Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);

  // .cookie = ibinderForJavaObject(env, object)得到一个JavaBBinder对象
  parcel->writeStrongBinder(ibinderForJavaObject(env, object))

a.3 ibinderForJavaObject(env, object) //object = new HelloService()
  把一个Java对象(new HelloService())转换为c++ IBinder对象

    JavaBBinderHolder* jbh = (JavaBBinderHolder*)env->GetLongField(obj, gBinderOffsets.mObject);
    return jbh != NULL ? jbh->get(env, obj) : NULL;
                b = new JavaBBinder(env, obj); // obj = new HelloService()
                      mObject = new HelloService()//在JavaBBinder的构造函数中执行

a.4 从驱动中得过了.cookie, 它是一个JavaBBinder对象
调用它的transact函数,导致JavaBBinder对象的onTransact被调用

JavaBBinder::onTransact (调用java里的某个函数)
  // mObject指向 HelloService对象
  // gBinderOffsets.mExecTransact指向: java Binder类中的execTransact方法
  // 调用HelloService(派生自Binder)对象中的execTransact方法
  jboolean res = env->CallBooleanMethod(mObject, gBinderOffsets.mExecTransact,code, reinterpret_cast<jlong>(&data), reinterpret_cast<jlong>(reply), flags);

a.5 java Binder的execTransact方法:
    res = onTransact(code, data, reply, flags);
        调用HelloService中的onTransact方法(来自IHelloService.Stube)
                  分辨数据
                    调用sayhello/sayhello_to

b.读取到的数据里含有.ptr/.cookie

它会把cookie转换成BBinder对象

调用它的transact函数

joinThreadPool()

{

  do{

    result = getAndExecuteCommand(); //

        result = talkWithDriver();//读取数据

        result = executeCommand(cmd);//分析数据

             对于BR_TRANSACTION数据

              sp<BBinder> b((BBinder*)tr.cookie);//把cookie转换成BBinder对象

              error = b->transact(tr.code,buffer,&reply,tr.flags)

  }

}

原文地址:https://www.cnblogs.com/liusiluandzhangkun/p/9159698.html

时间: 2024-09-30 06:26:09

9.13 Binder系统_Java实现_内部机制_Server端的相关文章

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层的sayh

9.7 Binder系统_c++实现_内部机制1

1. 内部机制_回顾binder框架关键点 binder进程通讯过程情景举例: test_server通过addservice向service_manager注册服务 test_client通过getservice向service_manager获取服务 然后test_client使用服务和test_server通讯 在上述通讯过程中涉及的对驱动访问: (1)注册服务过程add_service a.test_server为每个服务构造一个flat_binder_object结构体,不同服务结构体

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

内部机制_回顾binder框架关键点server注册服务时, 对每个服务都提供不同的ptr/cookie,在驱动程序里对每个服务都构造一个binder_node, 它也含有ptr/cookie client使用服务前要先getService:会在驱动程序里对该服务构造一个binder_ref, binder_ref含有desc, node成员, desc是整数, node指向对应服务的binder_node 使用服务时, client构造数据,调用ioctl:数据里含有handle 驱动程序根据

黑马程序员_Java基础_接口

------- android培训.java培训.期待与您交流! ---------- 0.接口知识体系 Java接口的知识体系如下图所示,掌握下图中的所有知识就可精通接口. 1.接口概论 1)接口概念 接口是从多个相似类中抽象出来的规范,接口中不包含普通方法,所有方法都是抽象方法,接口不提供实现.接口体现的是规范和实现分离的哲学.规范和实现分离正是接口的好处,让软件系统的各个组件之间面向接口耦合,是一种松耦合的设计.接口定义的是多个类共同的公共行为规范,定义的是一组公用方法. 2)接口与抽象类

内地客买30万重疾险香港便宜1 3 可保重疾多13种 香港 保险公司 保险_新浪财经_新浪网

买30万重疾险香港便宜1/3可保重疾多出13种 一群群内地客在香港海港城,排起长龙,炎热的夏天,时不时见有人用纸巾擦擦汗--这一幕不只是为了购买Gucci.LV等奢侈品,还有的为了香港保险公司的保单,有人戏谑香港保险代理签内地单签到"手软". 虽然到香港买保险,很多人心存疑虑,不少媒体也大称"地下保单"非法.无效,未来或存在理赔风险的告诫声也不绝于耳,但据香港保险业监理处统计,自2005年起,内地客新增保单保费总额从18.2亿港元上升到去年的149亿港元,增幅逾7倍

Linux嵌入式学习-远程过程调用-Binder系统

Binder系统的C程序使用示例IPC : Inter-Process Communication, 进程间通信RPC : Remote Procedure Call, 远程过程调用 这里我们直接只用android系统中已经实现好的Bindrt系统. 具体源代码在 frameworks\native\cmds\servicemanager\目录下. service_manager.c :a. binder_openb. binder_become_context_managerc. binder

Android Binder 系统学习笔记(一)Binder系统的基本使用方法

1.什么是RPC(远程过程调用) Binder系统的目的是实现远程过程调用(RPC),即进程A去调用进程B的某个函数,它是在进程间通信(IPC)的基础上实现的.RPC的一个应用场景如下: A进程想去打开LED,它会去调用led_open,然后调用led_ctl,但是如果A进程并没有权限去打开驱动程序呢? 假设此时有一个进程B由权限去操作LED驱动程序,那么进程A可以通过如下方式来操作LED驱动: ①封装数据,即A进程首先把想要调用的B进程的某个函数的(事先约定好的)代号等信息封装成数据包 ②A进

android数据存储_内部存储

源码下载(免下载积分):下载 你可以直接存储数据到内部存储中,默认情况下,文件存储到内部存储中是私有的,不能被 其他程序访问,当卸载应用程序,这些文件会被移除. 创建并写入数据可以有两种方法: 使用java中的相关的方法, 使用android.content中的相关方法,  调用 openFileOutput(),并返回FileOutputStream对象 调用FileOutputStream对象的write()方法 关闭流 读文件也是基本相同的方式. 在读文件有一点小技巧:如果想在编译时保存一

第7课第2节_Binder系统_c++实现_编译测试

七. Binder系统之服务的c++实现1. 编写代码参考文件:frameworks\av\include\media\IMediaPlayerService.h (IMediaPlayerService,BnMediaPlayerService)frameworks\av\media\libmedia\IMediaPlayerService.cpp (BpMediaPlayerService)frameworks\av\media\libmediaplayerservice\MediaPlay