APP Binder客户端调用全流程分析

APP Binder客户端调用全流程分析_第1张图片

 现在要搞明白JAVA层app调用跨进程的Service接口时,它的binder是怎样从Java->jni-->native--->binder驱动的这条链路:就是上图中的左半部分从上至下的流程。所以切入点在于,如app调用另一个进程的Service接口的getString()进行分析,如下:

myService.getString(); //调用服务接口
    -->进入aidl的getString():即IMyAidlInterface.Stub.Proxy.getString()
      -->mRemote.transact();
        -->IBinder.java->transact();
          -->BinderProxy.java->transact(); //还有一个是Binder.java那个是服务端的,所以这边要看BinderProxy客户端这边
            -->transactNative(code, data, reply, flags); //感觉到头了没路了,进入了JNI层(Zygote启动->JNI的注册,在那里面)

先来看看ZygoteInit.java做什么事。
app_main.cpp: //启动zygote
  -->runtime.start("...ZygoteInit", args,zygote);  
       -->startReg() //注册JNI
         -->register_jni_procs(gRegJNI,...); //注册了很多jNI接口  
         来看看gRegJNI[]={
             ...
             REG_JNI(register_android_os_Binder), //在这边注册,就是前面的
               -->android_util_Binder.cpp->int_register_android_os_BinderProxy():
                 -->gBinderProxyMethods[]={
                     //对应上面的transactNative的本地接口。
                     {"transactNaive", "(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z",(void*)android_os_BinderProxy_transact} 
                 }
             ...
         }        
 所以,前面调用到transactNative之后,就进入到JNI层的android_util_Binder.cpp中的
 android_os_BinderProxy_transact(.., jObject obj)处理。 
   -->这个obj是Binder Proxy.
      //将java的数据转成C++层的对象
      Parcel* data = parcelForJavaObject(env, dataObj);
      Parcel* reply = parcelForJavaObject(env, replyObj);

      //重要:调用getBPNativeData函数获得BinderProxy在Native中对应的BinderProxyNativeData
      //target本质上就是Native的BpBinder.
      IBinder *target = getBPNativeData(env, obj)->mObject.get();
        //下面这个语句就是反射。
        -->return (BinderProxyNativeData*)env->GetLongField(obj, gBinderProxyOffset.mNative);
      target->transact(code, *data, replay, flags);//这个直接进入了BpBinder.cpp的代码
即:   BpBinder.cpp->transact()
        //进入调用下面:创建并维持一个线程单例并调用transact接口
        -->IPCThreadState::self()->transact(mHandle, code, data, reply, flags);
          -->IPCThreadState.cpp->WaitForResponse();
              talkWithDriver();
                -->bwr.write_buffer = mOut.data();//设置缓存
                   ioctl(FD, BINDER_WRITE_READ, &bwr); //读写驱动
                   
              -->case BR_REPLY:
                 -->mIn.Read();
         

上面就是整体的调用流程,非常的清晰明了。

你可能感兴趣的:(Android系统,binder,android)