Android Binder框架实现之Java层Binder整体框架设计

  Android Binder框架实现之Java层Binder整体框架设计



Android Binder框架实现目录:

Android Binder框架实现之Binder的设计思想
Android Binder框架实现之何为匿名/实名Binder
Android Binder框架实现之Binder中的数据结构
Android Binder框架实现之Binder相关的接口和类
Android Binder框架实现之Parcel详解之基本数据的读写
Android Binder框架实现之Parcel read/writeStrongBinder实现
Android Binder框架实现之servicemanager守护进程
Android Binder框架实现之defaultServiceManager()的实现
Android Binder框架实现之Native层addService详解之请求的发送
Android Binder框架实现之Native层addService详解之请求的处理
Android Binder框架实现之Native层addService详解之请求的反馈
Android Binder框架实现之Binder服务的消息循环
Android Binder框架实现之Native层getService详解之请求的发送
Android Binder框架实现之Native层getService详解之请求的处理
Android Binder框架实现之Native层getService详解之请求的反馈
Android Binder框架实现之Binder Native Service的Java调用流程
Android Binder框架实现之Java层Binder整体框架设计
Android Binder框架实现之Framework层Binder服务注册过程源码分析
Android Binder框架实现之Java层Binder服务跨进程调用源码分析
Android Binder框架实现之Java层获取Binder服务源码分析


引言

  本文是Android Binder框架实现之Framework层Binder整体框架设计的起始篇,本文会重点讲述Android Binder框架Framework层整体设计思路及Framework Binder框架初始流程,想要了解Binder或者有所深入的读者,此系列博客你值得拥有!

注意:本篇的介绍是基于Android 7.xx平台为基础的,其中涉及的代码路径如下:

framework/base/core/java/android/os/
  ---IInterface.java
  ---IServiceManager.java
  ---ServiceManager.java
  ---ServiceManagerNative.java(内含ServiceManagerProxy类)

framework/base/core/java/android/os/
  ---IBinder.java
  ---Binder.java(内含BinderProxy类)
  ---Parcel.java

framework/base/core/java/com/android/internal/os/
  ---BinderInternal.java

framework/base/core/jni/
  ---AndroidRuntime.cpp
  ---android_os_Parcel.cpp
  ---android_util_Binder.cpp
  
frameworks/native/libs/binder/BpBinder.cpp
frameworks/native/include/binder/IBinder.h
frameworks/native/libs/binder/Binder.cpp
frameworks/native/include/binder/Parcel.h
frameworks/native/libs/binder/Parcel.cpp
frameworks/base/core/jni/core_jni_helpers.h
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java



一. Android Binder整体框架概述

  说到Android Java层Binder框架,如果抛开Native层的Binder避而不谈那就是纸上谈兵不切实际,如果我们将Android Native Binder比作是一颗树根的话,那么Java层的Binder就是就是这棵树的枝叶了,枝叶是不能离开根的,而根离开了枝叶依然可以存活(不接受反驳),其实我们可以把Java层的Binder理解我对Native层Binder的一种扩展或者封装,J_Binder依赖于C_Binder而存在,但是也是由于J_Binder的存在才能将Android Binder的框架发扬光大,提供了非常完善的Android生态功能(不可能让每个应用开发者都通过C++调用Native层服务吗,不信你让Android试试可行否)。所以总之用一句话概括Java层的Binder和Native层的Binder关系就是C_Binder是根基而J_Binder是扩展,二者相辅相成进而促成了Binder在Android世界不可动摇的地位。


1.1 Android Binder整体架构实现

  通过前面的博客Android Binder框架实现之Native层服务注册过程源码分析我们知道了Android Binder的核心框架层实现是在C++层实现的,但是我们也知道Android的绝大部分开发者和从业人员都是以Java语言为主的,所以Android的妈咪谷歌也充分考虑到了这种情况在Android Framework层也实现了一套Binder机制。看到这里你是不是有点蒙蔽了,难不成Android还搞了两种Binder机制!当然不是,这里Android Framework层的Binder和Native层的Binder是相辅相成,协同合作从而完成Android Binder的千秋大业的。

  前面遗留了一个小的知识点即Android Framework层和Native 层的Binder是怎么协同关联起来的呢?那就是Java和C++连接的万能膏药JNI技术了,Framework层的Binder通过JNI来调用(C/C++)层的Binder框架,从而为上层应用程序提供服务。 通过前面的博客我们知道在Native Binder层中,Binder采用的是C/S架构,分为Bn端(Server)和Bp端(Client)。而Java层在命名与架构上和Native也非常相近,基本上是无缝衔接,同样也实现了一套类似的IPC通信架构供应用开发使用(当然最后都是通过Native层的Binder框架实现的)。这里Framework层的Binder从另外一个层面来说,就是怼底层Native BInder的二次封装。Android BInder的整体框架图如下所示:

在这里插入图片描述


1.2 Android Binder类图

1.2.1 Android Native Binder类图

  在前面的博客Android Binder框架实现之Native层服务注册过程源码分析中我们知道了Android Native Binder的涉及的类图关系如下(前方高能,请做好心理准备,要理清楚这其中的关系得花费一费时间的):

在这里插入图片描述

  虽然我们在前面的博客对Android Native层的Binder类图关系有了详细的介绍,这里我们还是简单简单的归纳下:

  • BpBinder和BBinder共同继承与IBinder类,BpBinder是客户端进程中的Binder代理对象,BBinder是服务进程中用于IPC通信的工具对象,BpBinder类通过IPCThreadState类来与Binder驱动交互,访问服务进程中的BBinder,BpBinder代表了客户进程,BBinder代表了服务进程,数据从BpBinder发送到BBinder的整个过程就是Android系统的整个Binder通信过程,BpBinder与BBinder负责IPC通信,和上层业务并无关系。

  • Android系统的Binder通信实现了RPC远程调用,BpXXX和BnXXX则负责RPC远程调用的业务,XXX就代表不同的服务业务。BpXXX和BnXXX都实现了IXXX接口,IXXX定义了业务接口函数,BpXXX则是客户进程对服务进程中的BnXXX的影子对象,客户进程在调用服务进程中的某个接口函数时,只需调用BpXXX中的对应函数即可,BpXXX屏蔽了进程间通信的整个过程,让远程函数调用看起来和本地调用一样,这就是Android系统的Binder设计思想。

  • 进程要与Binder驱动交互,必须通过ProcessState对象来实现,ProcessState在每个使用了Binder通信的进程中唯一存在,其成员变量mDriverFD保存来/dev/binder设备文件句柄。对于某个服务来说,可能同时接受多个客户端的RPC访问,因此Android系统就设计了一个Binder线程池,每个Binder线程负责处理一个客户端的请求,对于每个Binder线程都存在一个属于自己的唯一IPCThreadState对象,IPCThreadState对象封装来Binder线程访问Binder驱动的接口,同一个进程中的所有Binder线程所持有的IPCThreadState对象使用线程本地存储来保存。

1.2.2 Android Java层Binder类图

  那么Android Framework层的Binder类图关系是啥样的呢!怎么说呢和Android Native层Binder类图关系基本上是一一对应的,但是又有所差别,其基本类图关系如下:
在这里插入图片描述

  是不是看到这个有点茫然无助的感觉,这里我们先简单介绍下(等在后续分析代码的时候可以将涉及到的相关类按图索翼,就理解起来容易了):

  • XXXManager:通过ServiceManager.getService方法可以获取到IXXXManagerService.Stub.Proxy对象,譬如我们通过该方法能获取到Android提供的的PMS,AMS,PKMS等相关服务的代理端。,然后我们可以通过该代理对象调用相关服务端完成指定的操作

  • IXXXManagerService.Stub.Proxy:其成员变量mRemote指向BinderProxy对象,IXXXManagerService.Stub.Proxy调用的相关方法最终是交由mRemote来完成相关操作的(注意这里的mRemote也是一个一个代理,真正完成相关的是在服务端)

  • IXXXManagerService.Stub:其方法asInterface()返回的是IXXXManagerService.Stub.Proxy对象,XXXManager便是借助IXXXManagerService.Stub类来找到IXXXManagerService.Stub.Proxy

  • Binder:其成员变量mObject和方法execTransact()用于native方法,和Native层Binder的BBinder对应

  • BinderInternal:内部有一个GcWatcher类,用于处理和调试与Binder相关的垃圾回收。

  • IBinder:接口中常量FLAG_ONEWAY:客户端利用binder跟服务端通信是阻塞式的,但如果设置了FLAG_ONEWAY,这成为非阻塞的调用方式,客户端能立即返回,服务端采用回调方式来通知客户端完成情况。另外IBinder接口有一个内部接口DeathDecipient(死亡通告)。

  • BinderProxy: 该类实现了IBinder接口,和Android Native Binder层的BpBinder是对应关系,最后借助BpBinder完成Binder间的数据传输

是不是上面的描述的描述还是有点抽象,那么以我们Framework层的ServiceManager(Java层的服务大管家)为例,将相关的实现带入类图(通常涉及到具体的实现会对Proxy和Stub类进行一下封装)。

在这里插入图片描述


1.3 Android Binder的层级关系

  通过前面1.1章节我们知道Android Java层和Native 层Binder之间是通过JNI串联起来的,那么这两者之间的层级关系如何呢?我这边小小的归纳总结了一下,可以用如下的两个图来表示:

在这里插入图片描述
在这里插入图片描述


1.4 Android Binder的类层级构架

  如果对Android Binder涉及的类图关系也进行一次分层划分,那么整个Binder从kernel至,Native,JNI,Framework层所涉及的全部类可以使用如下gityuan大神的图归纳总结一下:

在这里插入图片描述

这里对图中Java层和JNI层的几个类做一下说明

名称类型说明
IInterfaceinterface供Java层Binder服务接口继承的接口
IBinderinterfaceJava层的IBinder类,提供了transact方法来调用远程服务
Binderclass实现了IBinder接口,封装了JNI的实现。Java层Binder服务的基类
BinderProxyclass实现了IBinder接口,封装了JNI的实现。提供transact方法调用远程服务
JavaBBinderHolderclass内部存储了JavaBBinder
JavaBBinderclass将C++端的onTransact调用传递到Java端
ParcelclassJava层的数据包装器,见C++层的Parcel类分析

这里的IInterface,IBinder和C++层的两个类是同名的。这个同名并不是巧合:它们不仅仅同名,它们所起的作用,以及其中包含的接口都是几乎一样的,区别仅仅在于一个是C++层,一个是Java层而已。

除了IInterface,IBinder之外,这里Binder与BinderProxy类也是与C++的类对应的,下面列出了Java层和C++层类的对应关系:

C++Java层
IInterfaceIInterface
IBinderIBinder
BBinderBinder
BpProxyBinderProxy
ParcelParcel



二. Android Java层Binder框架的初始化

  通过前面博客Android之init进程启动源码分析我们可知Android Native Binder的大管家servicemanager进程及其相关的Native Binder Service进程是在init进程解析相关的init.xx.rc文件中的service块时启动的。那么我们的Android Framework Binder框架又是何时启动的呢?也许对Android启动过程有一定了解的小伙伴们会说是在system_server进程启动过程中,此时会启动相关核心服务并将其加入ServiceManager中。其实不然在Android Zygote进程启动源码分析指南中,我们知道Zygote进程会调用AndroidRuntime::startReg函数注册一系列的JNI函数,而这其中就包括我们的Android Framework层的Binder框架层相关的JNI,此时就标志着Framework层BInder框架的启动,而不是到了system_server进程才开始启动的。至于为什么要在此处注册,这个就留个小伙伴们自行思考了?


2.1 AndroidRuntime::startReg

//AndroidRuntime.cpp
static const RegJNIRec gRegJNI[] = {
	...
	REG_JNI(register_android_os_Binder),//详见章节2.2
	...
}
int AndroidRuntime::startReg(JNIEnv* env)
{
	...
    if (register_jni_procs(gRegJNI, NELEM(gRegJNI), env) < 0) {
        env->PopLocalFrame(NULL);
        return -1;
    }
	...

    return 0;
}

  这个流程没有过多好讲的,就是注册一系列的JNI方法,其中gRegJNI是一个数组保存了一系列的待注册的JNI方法列表,而这其中就包括我们今天的主人公Framework Binder相关的JNI方法register_android_os_Binder。


2.2 register_android_os_Binder

  这里顺带说一句,如果对JNI有不熟悉的小伙伴,强烈建议先阅读一下JNI/NDK入门指南,带你开启JNI世界的大门!

//android_util_Binder.cpp
int register_android_os_Binder(JNIEnv* env)
{
	//注册Binder类的JNI方法
	if (int_register_android_os_Binder(env) < 0)//详见章节2.3
        return -1;

	//注册BinderInteral类的JNI方法
    if (int_register_android_os_BinderInternal(env) < 0)//详见章节2.4
        return -1;

	//注册BinderProxy类的JNI方法
    if (int_register_android_os_BinderProxy(env) < 0)//详见章节2.5
        return -1;
	...
    return 0;
}

  register_android_os_Binder函数比较简单,就是调用另外的函数继续进行相关的Binder的JNI方法的注册。
在继续分析相关的函数前,我们来先看一下frameworks/base/core/jni/core_jni_helpers.h中对JNI环境提供的基本函数进行二次封装的相关工具函数集合(为啥要先介绍,因为后续会用到这些工具函数),如下:

//frameworks/base/core/jni/core_jni_helpers.h

/*
*查找对应Java类
*/
static inline jclass FindClassOrDie(JNIEnv* env, const char* class_name) {
    jclass clazz = env->FindClass(class_name);
    LOG_ALWAYS_FATAL_IF(clazz == NULL, "Unable to find class %s", class_name);
    return clazz;
}

/*
*返回类的实例(非静态)域的属性ID
*/
static inline jfieldID GetFieldIDOrDie(JNIEnv* env, jclass clazz, const char* field_name,
                                       const char* field_signature) {
    jfieldID res = env->GetFieldID(clazz, field_name, field_signature);
    LOG_ALWAYS_FATAL_IF(res == NULL, "Unable to find static field %s", field_name);
    return res;
}

/*
*返回Java类或者接口实例非静态方法的方法ID
*/
static inline jmethodID GetMethodIDOrDie(JNIEnv* env, jclass clazz, const char* method_name,
                                         const char* method_signature) {
    jmethodID res = env->GetMethodID(clazz, method_name, method_signature);
    LOG_ALWAYS_FATAL_IF(res == NULL, "Unable to find method %s", method_name);
    return res;
}
/*
*返回类的静态域的属性ID
*/
static inline jfieldID GetStaticFieldIDOrDie(JNIEnv* env, jclass clazz, const char* field_name,
                                             const char* field_signature) {
    jfieldID res = env->GetStaticFieldID(clazz, field_name, field_signature);
    LOG_ALWAYS_FATAL_IF(res == NULL, "Unable to find static field %s", field_name);
    return res;
}

/*
*返回类的静态方法ID
*/
static inline jmethodID GetStaticMethodIDOrDie(JNIEnv* env, jclass clazz, const char* method_name,
                                               const char* method_signature) {
    jmethodID res = env->GetStaticMethodID(clazz, method_name, method_signature);
    LOG_ALWAYS_FATAL_IF(res == NULL, "Unable to find static method %s", method_name);
    return res;
}

/*
*基于局部引用创建一个全局引用
*/
template <typename T>
static inline T MakeGlobalRefOrDie(JNIEnv* env, T in) {
    jobject res = env->NewGlobalRef(in);
    LOG_ALWAYS_FATAL_IF(res == NULL, "Unable to create global reference.");
    return static_cast<T>(res);
}

/*
*注册Java类对应的JNI方法
*/
static inline int RegisterMethodsOrDie(JNIEnv* env, const char* className,
                                       const JNINativeMethod* gMethods, int numMethods) {
    int res = AndroidRuntime::registerNativeMethods(env, className, gMethods, numMethods);
    LOG_ALWAYS_FATAL_IF(res < 0, "Unable to register native methods.");
    return res;
}

2.3 int_register_android_os_Binder

  小伙伴们,这个标题没有错,不要怀疑我是把2.2的标题给复制了一篇粘贴过来了。

//android_util_Binder.cpp
const char* const kBinderPathName = "android/os/Binder";
static int int_register_android_os_Binder(JNIEnv* env)
{
	//kBinderPathName = "android/os/Binder",用来查找kBinderPathName路径所属的类,即我们的Binder.java
	jclass clazz = FindClassOrDie(env, kBinderPathName);//关于该函数的功能参见2.2

	//将Java层的Binder类保存到mClass中
	gBinderOffsets.mClass = MakeGlobalRefOrDie(env, clazz);//关于该函数的功能参见2.2
	//将Java层execTransact()方法保存到mExecTransact变量
    gBinderOffsets.mExecTransact = GetMethodIDOrDie(env, clazz, "execTransact", "(IJJI)Z");//关于该函数的功能参见2.2
	//将Java层的mObject属性保存到mObject中
	gBinderOffsets.mObject = GetFieldIDOrDie(env, clazz, "mObject", "J");//关于该函数的功能参见2.2

    return RegisterMethodsOrDie(
        env, kBinderPathName,
        gBinderMethods, NELEM(gBinderMethods));
}

  有了前面章节2.2最后关于JNI工具函数的的知识铺垫int_register_android_os_Binder函数应该理解起来就很简单了,主要干了两件事情:

  • 将Java层Binder类的相关信息保存到gBinderOffsets结构体中,供后面Framework层Binder框架使用(关于结构体gBinderOffsets详见2.3.1)
  • 调用RegisterMethodsOrDie函数,动态注册Java层Binder类的对应的JNI方法(具体注册了那些JNI方法详见2.3.2)
2.3.1 bindernative_offsets_t
//android_util_Binder.cpp
static struct bindernative_offsets_t
{
    jclass mClass;//   保存Java层Binder类信息
    jmethodID mExecTransact;// 保存Java层Binder类execTransact()方法ID

    jfieldID mObject;//保存Java层Binder类mObject属性域ID

} gBinderOffsets;

  这里的gBinderOffsets是全局静态结构体变量,该结构体主要的功能是用来设计保存Java层Binder类本身以及其成员方法execTransact()和成员属性mObject的,这为JNI层访问Java层提供通道。另外通过查询获取Java层Binder信息后保存到gBinderOffsets,而不是每次在需要使用Binder的时候再来进行相关的查找这样能大幅的提高效率,这是由于每次查询需要花费较多的CPU时间,尤其是频繁访问时,但是我们这里提前使用额外的结构体来保存这些信息,是以空间换时间的方法来达到提升效率(现在的Android设备存储空间都比较大,所以这些开销基本可以忽略不计)。

2.3.2 gBinderMethods
//jni.h
typedef struct {
    const char* name;//Java本地方法名称
    const char* signature;//Java本地方法签名
    void*       fnPtr;//对应的JNI函数
} JNINativeMethod;
//android_util_Binder.cpp
static const JNINativeMethod gBinderMethods[] = {
     /* name, signature, funcPtr */
    { "getCallingPid", "()I", (void*)android_os_Binder_getCallingPid },
    { "getCallingUid", "()I", (void*)android_os_Binder_getCallingUid },
    { "clearCallingIdentity", "()J", (void*)android_os_Binder_clearCallingIdentity },
    { "restoreCallingIdentity", "(J)V", (void*)android_os_Binder_restoreCallingIdentity },
    { "setThreadStrictModePolicy", "(I)V", (void*)android_os_Binder_setThreadStrictModePolicy },
    { "getThreadStrictModePolicy", "()I", (void*)android_os_Binder_getThreadStrictModePolicy },
    { "flushPendingCommands", "()V", (void*)android_os_Binder_flushPendingCommands },
    { "init", "()V", (void*)android_os_Binder_init },
    { "destroy", "()V", (void*)android_os_Binder_destroy },
    { "blockUntilThreadAvailable", "()V", (void*)android_os_Binder_blockUntilThreadAvailable }
};

  这里的gBinderMethods是一个全局的结构体数组,通过RegisterMethodsOrDie将该结构体数组中的本地方法和JNI函数建立一一对应的关系,通俗的来讲就是JNI的动态注册。

  经过上面的操作以后建立了Java层到JNI层的访问通道,进而为打通Java层和Native层之间的通道做好了前期的准备,此时也标志着Framework层的Binder和Native 层Binder之间的连接桥梁已经开始进行施工了。


2.4 int_register_android_os_BinderInternal

//android_util_Binder.cpp
const char* const kBinderInternalPathName = "com/android/internal/os/BinderInternal";
static int int_register_android_os_BinderInternal(JNIEnv* env)
{
    jclass clazz = FindClassOrDie(env, kBinderInternalPathName);

    gBinderInternalOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
    gBinderInternalOffsets.mForceGc = GetStaticMethodIDOrDie(env, clazz, "forceBinderGc", "()V");

    return RegisterMethodsOrDie(
        env, kBinderInternalPathName,
        gBinderInternalMethods, NELEM(gBinderInternalMethods));
}

  有了前面的分析,这里的流程基本就是依葫芦画瓢了,int_register_android_os_BinderInternal函数主要干了如下两件事情:

  • 将Java层BinderInternal类的相关信息保存到gBinderInternalOffsets结构体中,供后面Framework层Binder框架使用(关于结构体gBinderInternalOffsets详见2.4.1)
  • 调用RegisterMethodsOrDie函数,动态注册Java层BinderInternal类的对应的JNI方法(具体注册了那些JNI方法详见2.4.2)
2.4.1 binderinternal_offsets_t
//android_util_Binder.cpp
static struct binderinternal_offsets_t
{
    
    jclass mClass;//保存Java层BinderInternal类信息
    jmethodID mForceGc;//保存Java层BinderInternal类forceBinder()方法ID

} gBinderInternalOffsets;

  这里的gBinderInternalOffsets是全局静态结构体变量,该结构体主要的功能是用来设计保存Java层BinderInternal类本身以及其成员方法forceBinder()信息。

2.4.2 gBinderInternalMethods

  这里的gBinderInternalMethods也是一个全局的结构体数组,保存的是BinderInternal类本地方法以及对应的JNI方法对应关系表,如下所示:

//jni.h
typedef struct {
    const char* name;//Java本地方法名称
    const char* signature;//Java本地方法签名
    void*       fnPtr;//对应的JNI函数
} JNINativeMethod;
//android_util_Binder.cpp
static const JNINativeMethod gBinderInternalMethods[] = {
     /* name, signature, funcPtr */
    { "getContextObject", "()Landroid/os/IBinder;", (void*)android_os_BinderInternal_getContextObject },
    { "joinThreadPool", "()V", (void*)android_os_BinderInternal_joinThreadPool },
    { "disableBackgroundScheduling", "(Z)V", (void*)android_os_BinderInternal_disableBackgroundScheduling },
    { "setMaxThreads", "(I)V", (void*)android_os_BinderInternal_setMaxThreads },
    { "handleGc", "()V", (void*)android_os_BinderInternal_handleGc }
};

  分析至此,Framework层的BinderInternal类和JNI之间的关系已经建立,进而为后续Android Framewrok层Binder和Native层Binder关系的建立夯实了坚定的基础。


2.5 int_register_android_os_BinderProxy

//android_util_Binder.cpp
const char* const kBinderProxyPathName = "android/os/BinderProxy";
static int int_register_android_os_BinderProxy(JNIEnv* env)
{
     //gErrorOffsets保存了Error类信息
    jclass clazz = FindClassOrDie(env, "java/lang/Error");
    gErrorOffsets.mClass = MakeGlobalRefOrDie(env, clazz);

    //gBinderProxyOffsets保存了BinderProxy类的信息
    //其中kBinderProxyPathName = "android/os/BinderProxy"
    clazz = FindClassOrDie(env, kBinderProxyPathName);
    gBinderProxyOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
    gBinderProxyOffsets.mConstructor = GetMethodIDOrDie(env, clazz, "<init>", "()V");
    gBinderProxyOffsets.mSendDeathNotice = GetStaticMethodIDOrDie(env, clazz, "sendDeathNotice",
            "(Landroid/os/IBinder$DeathRecipient;)V");

    gBinderProxyOffsets.mObject = GetFieldIDOrDie(env, clazz, "mObject", "J");
    gBinderProxyOffsets.mSelf = GetFieldIDOrDie(env, clazz, "mSelf",
                                                "Ljava/lang/ref/WeakReference;");
    gBinderProxyOffsets.mOrgue = GetFieldIDOrDie(env, clazz, "mOrgue", "J");
    
	//gClassOffsets保存了Class.getName()方法
    clazz = FindClassOrDie(env, "java/lang/Class");
    gClassOffsets.mGetName = GetMethodIDOrDie(env, clazz, "getName", "()Ljava/lang/String;");

    return RegisterMethodsOrDie(
        env, kBinderProxyPathName,
        gBinderProxyMethods, NELEM(gBinderProxyMethods));
}

  依然是老套路,还是来个依葫芦画瓢算了,int_register_android_os_BinderProxy函数主要干了如下两件事情:

  • 将Java层BinderProxy类的相关信息保存到gBinderProxyOffsets结构体中,供后面Framework层Binder框架使用(关于结构体gBinderProxyOffsets详见2.5.1)
  • 调用RegisterMethodsOrDie函数,动态注册Java层BinderProxy类的对应的JNI方法(具体注册了那些JNI方法详见2.4.2)
2.5.1 binderproxy_offsets_t
//android_util_Binder.cpp
static struct binderproxy_offsets_t
{
    
    jclass mClass;
    jmethodID mConstructor;
    jmethodID mSendDeathNotice;

    
    jfieldID mObject;
    jfieldID mSelf;
    jfieldID mOrgue;

} gBinderProxyOffsets;

  这里的gBinderProxyOffsets是全局静态结构体变量,该结构体主要的功能是用来设计保存Java层BinderProxy类本身以及其成员方法ID和变量域ID等相关信息。

2.5.2 gBinderProxyMethods

  这里的gBinderProxyMethods也是一个全局的结构体数组,保存的是BinderProxy类本地方法以及对应的JNI方法对应关系表,如下所示:

//jni.h
typedef struct {
    const char* name;//Java本地方法名称
    const char* signature;//Java本地方法签名
    void*       fnPtr;//对应的JNI函数
} JNINativeMethod;
//android_util_Binder.cpp
static const JNINativeMethod gBinderProxyMethods[] = {
     /* name, signature, funcPtr */
    {"pingBinder",          "()Z", (void*)android_os_BinderProxy_pingBinder},
    {"isBinderAlive",       "()Z", (void*)android_os_BinderProxy_isBinderAlive},
    {"getInterfaceDescriptor", "()Ljava/lang/String;", (void*)android_os_BinderProxy_getInterfaceDescriptor},
    {"transactNative",      "(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z", (void*)android_os_BinderProxy_transact},//这个函数是重点
    {"linkToDeath",         "(Landroid/os/IBinder$DeathRecipient;I)V", (void*)android_os_BinderProxy_linkToDeath},
    {"unlinkToDeath",       "(Landroid/os/IBinder$DeathRecipient;I)Z", (void*)android_os_BinderProxy_unlinkToDeath},
    {"destroy",             "()V", (void*)android_os_BinderProxy_destroy},
};

  分析至此,Framework层的BinderProxy类和JNI之间的关系已经建立,进而为后续Android Framewrok层Binder和Native层Binder关系的建立夯实了坚定的基础。


2.6 Android Java层Binder框架的初始化小结

  到这里Android Framework层Binder框架在Zygote进程中的初始化也告一段落了,通过这一些列的初始化工作Android Framework层的Binder和JNI建立起了相关的关联,进而为后续的和Native Binder关联建立起了通道。此时关于Android Framework层Binder相关类和JNI之间的联系,可以使用下述的图示来表示,如下:

在这里插入图片描述




写在最后

  至此Android Binder Framework层的整体框架和初始化流程就到这里告一段落了,本篇是Android Binder框架实现之Framework层Binder系列介绍的开篇,在接下来的篇章中将会分析到Java 层Binder服务的注册,获取,以及第三方应用远程调用Java Binder服务的整个流程。这里先行做一个预告,希望大家后续继续关注Android Binder框架实现之Framework层Binder的系列篇章。好了就到这里了,欢迎小伙伴们评论和点赞,后续篇章继续分析。

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值