binder java层_理解 Android Binder 机制(三):Java层

理解 Android Binder 机制(三):Java层

时间:2017-03-25

来源:互联网

分享到:

下文所讲内容的相关源码,在AOSP源码树中的路径如下:

// Binder Framework JNI

/frameworks/base/core/jni/android_util_Binder.h

/frameworks/base/core/jni/android_util_Binder.cpp

/frameworks/base/core/jni/android_os_Parcel.h

/frameworks/base/core/jni/android_os_Parcel.cpp

// Binder Framework Java接口

/frameworks/base/core/java/android/os/Binder.java

/frameworks/base/core/java/android/os/IBinder.java

/frameworks/base/core/java/android/os/IInterface.java

/frameworks/base/core/java/android/os/Parcel.java

主要结构

Android应用程序使用Java语言开发,Binder框架自然也少不了在Java层提供接口。

前文中我们看到,Binder机制在C++层已经有了完整的实现。因此Java层完全不用重复实现,而是通过JNI衔接了C++层以复用其实现。

下图描述了Binder Framework Java层到C++层的衔接关系。

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

除了IInterface,IBinder之外,这里Binder与BinderProxy类也是与C++的类对应的.JNI的衔接

JNI全称是Java Native Interface,这个是由Java虚拟机提供的机制。这个机制使得native代码可以和Java代码互相通讯。简单来说就是:我们可以在C/C++端调用Java代码,也可以在Java端调用C/C++代码。

关于JNI的详细说明,可以参见Oracle的官方文档:Java Native Interface ,这里不多说明。

实际上,在Android中很多的服务或者机制都是在C/C++层实现的,想要将这些实现复用到Java层,就必须通过JNI进行衔接。AOSP源码中,/frameworks/base/core/jni/ 目录下的源码就是专门用来对接Framework层的JNI实现的。

看一下Binder.java的实现就会发现,这里面有不少的方法都是用native关键字修饰的.

并且没有方法实现体,这些方法其实都是在C++中实现的:

public static final native int getCallingPid();

public static final native int getCallingUid();

public static final native long clearCallingIdentity();

public static final native void restoreCallingIdentity(long token);

public static final native void setThreadStrictModePolicy(int policyMask);

public static final native int getThreadStrictModePolicy();

public static final native void flushPendingCommands();

public static final native void joinThreadPool();

在android_util_Binder.cpp文件中的下面这段代码,设定了Java方法与C++方法的对应关系:

static const JNINativeMethod gBinderMethods[] = {

{ "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 }

};

这种对应关系意味着:当Binder.java中的getCallingPid方法被调用的时候,真正的实现其实是android_os_Binder_getCallingPid,当getCallingUid方法被调用的时候,真正的实现其实是android_os_Binder_getCallingUid,其他类同。

然后我们再看一下android_os_Binder_getCallingPid方法的实现就会发现,这里其实就是对接到了libbinder中了:

static jint android_os_Binder_getCallingPid(JNIEnv* env, jobject clazz)

{

return IPCThreadState::self()->getCallingPid();

}

这里看到了Java端的代码是如何调用的libbinder中的C++方法的。那么,相反的方向是如何调用的呢?最关键的,libbinder中的BBinder::onTransact是如何能够调用到Java中的Binder::onTransact的呢?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值