ITKeyword,专注技术干货聚合推荐

注册 | 登录

Android系统进程间通信Binder机制在应用程序框架层的Java接口源代码文件分析

dajian790626 分享于 2012-02-17

推荐:Android系统进程间通信Binder机制在应用程序框架层的Java接口源代码分析

       在前面几篇文章中,我们详细介绍了Android系统进程间通信机制Binder的原理,并且深入分析了系统提供的Binder运行库和驱动程序的源代码。细心的读者会发现

2020腾讯云“6.18”活动开始了!!!(巨大优惠重现!4核8G,5M带宽 1999元/3年),
地址https://cloud.tencent.com/act/cps/redirect?redirect=1059

2020阿里云最低价产品入口,含代金券(新老用户有优惠),
地址https://www.aliyun.com/minisite/goods

 

Android系统进程间通信Binder机制在应用程序框架层的Java接口源代码分析----------------------------

bind涉及的文件------------------------------------------------------------------------------------------>

1、JAVA层相关:--------------------------<BinderProxy对象是关键>-----------

---ServiceManager.java

public final class ServiceManager{

private static IServiceManager sServiceManager;//定义一个IServiceManager静态类对象成员,保存ServiceManager的代理ServiceManagerProxy。

它通过函数getIServiceManager来获取初值。

 

getIServiceManager()函数很重要,它定义和生成了JAVA层ServiceManager的代理ServiceManagerProxy和Binder的代理BinderProxy(通过调用JNI函数getContextObject在JNI层获取的)。定义如下:

    private static IServiceManager getIServiceManager() {

        if (sServiceManager != null) {

            return sServiceManager;

        }

 

        // Find the service manager

        sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());

 

       // this statement is equal

       //sServiceManager = ServiceManagerNative.asInterface(new BinderProxy());

       //sServiceManager = new ServiceManagerProxy(new BinderProxy());

       //end

      

        return sServiceManager;

    }

***首先通过BinderInternal的getContextObject方法得到一个BinderProxy对象。getContextObject是一个JNI调用,在JNI(android_util_Binder.cpp)中实现new一个BinderProxy返回。

***其次通过ServiceManagerNative的方法asInterface得到(new)一个ServiceManagerProxy对象。并将BinderProxy对象保存到类成员mRemote中。

***此函数使我们在Java层,拥有了一个Service Manager远程接口ServiceManagerProxy,而这个ServiceManagerProxy对象在JNI层有一个句柄值为0的BpBinder对象与之通过gBinderProxyOffsets(或者说BinderProxy.mObject保存有BpBinder对象的地址)关联起来。

 

}

getIServiceManager函数用到了ServiceManagerNative和BinderInternal类。

 

---IServiceManager.java

public interface IServiceManager extends IInterface{}继承自IInterface接口,本身还是接口。

此文件定义一个接口,其中声明了和C++相似的交互接口,以及各类操作的消息。

 

---ServiceManagerNative.java

public abstract class ServiceManagerNative extends Binder implements {}

定义了类ServiceManagerNative(本地)

ServiceManagerNative继承自Binder,并实现IServiceManager的接口。它的asInterface()提供一个ServiceManagerProxy对象。

 

class ServiceManagerProxy implements IServiceManager {}

定义了类ServiceManagerProxy(代理)

ServiceManagerProxy继承自IServiceManager,并实现了其声明的操作函数,只会被ServiceManagerNative创建,

它实现了IServiceManager的接口,IServiceManager提供了getService和addService两个成员函数来管理系统中的Service。

 

---BinderInternal.java

public class BinderInternal{}此类主要用来提供一些测试用的接口,都是JNI调用。

同时方法getContextObject通过JNI得到BinderProxy对象,用来给JAVA层提供调用。

 

JNI层的函数对应如下:

    static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz) 

    { 

        sp<IBinder> b = ProcessState::self()->getContextObject(NULL); 

        return javaObjectForIBinder(env, b); 

    } 

sp<IBinder> b = ProcessState::self()->getContextObject(NULL); 

相当于

sp<IBinder> b = new BpBinder(0);

接着调用javaObjectForIBinder把这个BpBinder对象转换成一个BinderProxy对象

 

注意:

gBinderOffsets变量是用来记录JAVA层Binder类的相关信息的,它是在注册Binder类的JNI方法的int_register_android_os_Binder函数初始化的;

gBinderProxyOffsets是用来变量是用来记录JAVA层BinderProxy类的相关信息的,它是在注册BinderProxy类的JNI方法的int_register_android_os_BinderProxy函数初始化的。

 

推荐:Android系统进程间通信(IPC)机制Binder中的Server启动过程源代码分析

 在前面一篇文章浅谈Android系统进程间通信(IPC)机制Binder中的Server和Client获得Service Manager接口之路中,介绍了在Android系统中Binder进程间通信机制中

在函数javaObjectForIBinder中创建了一个BinderProxy对象:

object = env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor);

 

C++层的BpBinder对象和JAVA层的BinderProxy对象关联,是通过函数javaObjectForIBinder中的如下语句,

    env->SetIntField(object, gBinderProxyOffsets.mObject, (int)val.get()); 

建立的,BinderProxy.mObject成员变量记录了这个BpBinder对象的地址。

同时使用,

    val->attachObject(&gBinderProxyOffsets, refObject, 

                    jnienv_to_javavm(env), proxy_cleanup); 

把BinderProxy的地址放到BpBinder里面去,以后通过调用BpBinder::findObj可以找到。

 

 

---Binder.java

public class Binder implements IBinder{}

final class BinderProxy implements IBinder{}

此文件定义Binder和BinderProxy类

 

Binder实现的IBinder的接口,他的大部分函数都是通过JNI调用底层实现的。

 

BinderProxy是JAVA层的关键类,在JNI通过gBinderProxyOffsets来使用。

 

---IInterface.java

public interface IInterface{}

此文件只定义JAVA的接口IInterface,其内生命了asBinder函数,返回值为IBinder对象。

 

---IBinder.java

public interface IBinder {}

此文件只定义了接口IBinder。此接口声明了接口紧密相关的几个方法。

 

---Parcel.java

public final class Parcel {}

Parcel类是用Java来实现的,它跟用C++实现的Parcel类的作用是一样的,即用来在两个进程之间传递数据。

 

2、C++层相关:------------------------------<BpBinder是关键>-----------

BpBinder.cpp

BpBinder.h

 

sp<IBinder> b = ProcessState::self()->getContextObject(NULL);

相当于,

sp<IBinder> b = new BpBinder(0);

 

3、JNI相关文件:------------------------<JavaBBinderHolder和JavaBBinder是关键>-----------

android_util_Binder.cpp

       class JavaBBinder : public BBinder JavaBBinder继承自C++的BBinder类

      

       int_register_android_os_Binder()注册Binder类的JNI方法

      

       static const JNINativeMethod gBinderMethods[] JAVA和C++层函数映射表

       register_android_os_Binder此函数用来注册所有类型的JNI

 

       class JavaBBinderHolder : public RefBase{}

       此类是实现JNI的关键类对象。

       我们就是要把JavaBBinderHolder里面的JavaBBinder类型Binder实体添加到Service Manager中去,以便使得这个HelloService有Client来请求服务时,由Binder驱动程序来唤醒这个Server线程,进而调用这个JavaBBinder类型Binder实体的onTransact函数来进一步处理,这个函数我们在后面会继续介绍。

 

       class JavaBBinder : public BBinder{}

 

android_util_Binder.h

       函数,

       android_os_BinderInternal_getContextObject

       gBinderInternalMethods表

Jni.h

 

JNIHelp.c

jniRegisterNativeMethods注册JNI函数

推荐:Android系统进程间通信(IPC)机制Binder中的Client获得Server远程接口过程源代码分析

在上一篇文章中,我们分析了Android系统进程间通信机制Binder中的Server在启动过程使用Service Manager的addService接口把自己添加到Service Manager守护过程中

  Android系统进程间通信Binder机制在应用程序框架层的Java接口源代码分析---------------------------- bind涉及的文件--------------------------------------------------------------------

相关阅读排行


相关内容推荐

最新文章

×

×

请激活账号

为了能正常使用评论、编辑功能及以后陆续为用户提供的其他产品,请激活账号。

您的注册邮箱: 修改

重新发送激活邮件 进入我的邮箱

如果您没有收到激活邮件,请注意检查垃圾箱。