• 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: frameworksasecmdsapp_processapp_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)

      }

    }

  • 相关阅读:
    Error Correct System(模拟)
    Pasha and String(思维,技巧)
    Vitaliy and Pie(模拟)
    Old Sorting(转化成单调序列的最小次数,置换群思想)
    Segment(技巧 相乘转换成相加 + java)
    Conquering Keokradong && Get the Containers(二分)
    Handshakes(思维) 2016(暴力)
    Dice Notation(模拟)
    “玲珑杯”郑州轻工业学院第八届ACM程序设计大赛暨河南高校邀请赛-正式赛(总结)
    MySQL安装-二进制软件包安装
  • 原文地址:https://www.cnblogs.com/liusiluandzhangkun/p/9159698.html
Copyright © 2020-2023  润新知