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)

  }

}

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

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

    Java实现中client端的RPC层(java实现)如何通过JNI来调用IPC层(C++实现)发送数据 TestServer通过addService向Service_manager注册的时候Test ...

  2. 9.8 Binder系统_c++实现_内部机制1

    1. 内部机制_回顾binder框架关键点 binder进程通讯过程情景举例: test_server通过addservice向service_manager注册服务 test_client通过get ...

  3. 9.10 Binder系统_Java实现_hello服务

    怎么做?2.1 定义接口: 写IHelloService.aidl文件, 上传, 编译, 得到IHelloService.java 里面有Stub : onTransact, 它会分辨收到数据然后调用 ...

  4. 9.9 Binder系统_Java实现_Android里java程序的编译启动

    如果知道了进程号:通过ls /proc/进程号/task 可以看到所有线程    cat /proc/进程号/task/线程号/comm  可以达到线程名字(主线程是main,主线程号就是进程号) d ...

  5. 9.7 Binder系统_c++实现_编写程序

    参考文件:frameworks\av\include\media\IMediaPlayerService.h (IMediaPlayerService,BnMediaPlayerService)fra ...

  6. 9.2 Binder系统_驱动情景分析_服务注册过程

    1. 几个重要结构体的引入给test_server添加一个goodbye服务, 由此引入以下概念: 进程间通信其实质也是需要三要素:源.目的.数据,源是自己,目的用handle表示:通讯的过程是源向实 ...

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

    内部机制_回顾binder框架关键点server注册服务时, 对每个服务都提供不同的ptr/cookie,在驱动程序里对每个服务都构造一个binder_node, 它也含有ptr/cookie cli ...

  8. 9.11 Binder系统_分层

    1.Binder系统过程分析,情景分析 server提供服务 (1)addService(服务名称,xxx)执行后会导致binder驱动在server的内核空间为服务创建一个binder_node结构 ...

  9. 012_STM32程序移植之_内部flash开机次数管理lib库建立

    012_STM32程序移植之_内部flash开机次数管理lib库建立 1. 测试环境:STM32C8T6 2. 测试接口: 3. 串口使用串口一,波特率9600 单片机引脚------------CH ...

随机推荐

  1. 3.索引与string进行映射实现高效查找

    #include <iostream> #include <typeindex>//类型索引 #include <unordered_map>//红黑树 #incl ...

  2. POJ 3175 枚举

    思路: 枚举小数点前 的数是啥 判一判 复杂度是根号的-.. 注意精度!!!! //By SiriusRen #include <cmath> #include <cstdio> ...

  3. Redhat Linux下如何使用KVM虚拟机(视频)

    KVM(kernel-basedVirtualMachine)是一个开源的系统虚拟化模块,自Linux2.6.20之后集成在Linux的各个主要发行版本中.它使用Linux自身的调度器进行管理,所以相 ...

  4. vue 点击事件阻止冒泡 用stop

    1.使用vue阻止子级元素的click事件冒泡,很简单,用stop.eg: @click.stop='xxx'

  5. learn ES6

    介绍 ES6,也叫ECMAScript2015(以下统称ES6),是ECMAScript标准的最新版本.这个标准在2015年6月份被正式批准.ES6是js语言很有意义的一次更新,也是2009年ES5被 ...

  6. PHP 获取完整URL地址

    /** * 获取当前完整URL * @return string */ function get_url() { $sys_protocal = isset($_SERVER['SERVER_PORT ...

  7. Matlab piecelin

    function v = piecelin(x,y,u) %PIECELIN Piecewise linear interpolation. % v = piecelin(x,y,u) finds t ...

  8. js29--装饰着模式

    //装饰者模式:就是在保证不改变原有对象的基础上,去扩展一些想要的方法或去求 var CarInterface = new BH.Interface('CarInterface' , ['getPri ...

  9. asp.net 前后台数据交互方式(转)

    https://blog.csdn.net/luckyrass/article/details/38758007 一.前台直接输出后台传递的数据 后台代码: // .aspx.cs public st ...

  10. eclipse创建maven

    第一步: 第二步 第三步: 第四步: 第五步: 第六步: <?xml version="1.0" encoding="UTF-8"?> <we ...