第6章 Binder在Java框架层的实现

在Binder的体系结构中,分为Native框架层和Java框架层。在第5章中,以Native系统服务为例详细分析了Binder在Native框架层的机制与实现,本章分析Binder在Java框架层的机制与实现。那么在Java框架层的哪些地方需要使用Binder机制呢?

应用框架层为应用开发者提供了Android四大组件:Activity、Service、Content Provider和Broadcast Receiver。这四大组件都是由Java代码实现的,不同的组件可以位于不同的进程中,例如:一个Activity启动其他Activity;Activity与Service交互;Activity通过Content Provider访问其他应用程序的数据;一个组件发送广播给其他组件处理。这四种情况下都需要用到Binder通信。Android四大组件能够进行Binder通信的基础是应用框架层提供的系统服务,即SystemServer在init2阶段启动的Java系统服务。

Binder在Java框架层的应用并不仅限于四大组件的交互,在四大组件中也可以通过应用框架层提供的getSystemService接口直接使用Java系统服务。

从上面五种场景可以看出,在Java框架层,Binder仍然是C/S体系结构的黏合剂,它将C/S架构中的Client端和Server端无缝地连接在一起,让上层应用程序感觉不到不同进程的存在。Binder的Java框架层与Native框架层一样,具备C/S体系结构的主要组成部分:Client、Proxy、Stub、Server和Service。Java框架层并没有提供类似Native框架层的servicemanager进程,而是通过ServiceManager(Java)类使用JNI复用了Native框架层的servicemanager,因此ServiceManager(Java)相当于Native层的servicemanager在Java框架层的代理。此外,Java框架层通过JNI将Native框架层的BpBinder和BBinder封装为Java对象,供Java框架层使用。为了便于Java框架层开发系统服务,在Java框架层中提供了AIDL工具用于生成统一的Proxy和Stub接口。本章以Java系统服务为例,分析Binder在Java框架层的实现。

6.1 Java系统服务的创建过程

Java系统服务在Android启动过程的init2阶段由ServiceThread启动,并注册到Service Manager。init2阶段的启动流程在第4章已经分析过,本节以power系统服务为例分析Java系统服务的创建过程,该服务由PowerManagerService实现,其启动过程位于ServiceThread中。

ServiceThread定义于frameworks/base/services/java/com/android/server/SystemServer.java中。创建和注册power服务的代码如下:


class ServerThread extends Thread{

……

public void run(){//run方法在SystemServer启动的init2阶段被执行

……

PowerManagerService power=null;

try{

power=new PowerManagerService();//启动power服务

//注册power服务到ServiceManager中

ServiceManager.addService(Context.POWER_SERVICE, power);

……

}catch(RuntimeException e){

}

}


注意 Java系统服务与Native系统服务的创建和注册过程有很多相似之处,都是首先创建并启动系统服务,然后将该服务注册到ServiceManager中。本节只分析power系统服务的创建过程,下一节分析其注册过程,power服务的运行过程与Binder框架层的体系结构联系不多,不再分析。

PowerManagerService定义于frameworks/base/services/java/com/android/server/PowerManager Service.java中,首先分析PowerManagerService的继承关系,如图6-1所示。

PowerManagerService继承自Stub类,Stub是定义于IPowerManager接口的内部抽象类,Stub继承自android.os.Binder类并实现了IPo-werManager接口,代码如下:


public class PowerManagerService

extends IPowerManager.Stub

implements LocalPowerManager,

Watchdog.Monitor{


从PowerManagerService的继承结构可以看出,在创建PowerManagerService对象的过程中,会调用其继承树上所有父类的构造方法,其中最重要的构造方法便是父类Binder的构造方法,Binder类定义于frameworks/base/core/java/android/os/Binder.java中。

第6章 Binder在Java框架层的实现 - 图1

图 6-1 PowerManagerService的继承关系

在Binder的构造方法中,调用了关键的init()方法,这是一个Native方法,其JNI实现方法位于frameworks/base/core/jni/android_util_Binder.cpp中,代码如下:


static void android_os_Binder_init(JNIEnv*env, jobject obj)

{

/*创建JavaBBinderHolder对象,该对象继承自RefBase,在其内部

将持有一个JavaBBinder对象的wp指针/

JavaBBinderHolder*jbh=new JavaBBinderHolder();

if(jbh==NULL){

jniThrowException(env,"java/lang/OutOfMemoryError",NULL);

return;

}

//增加引用计数

jbh->incStrong((void*)android_os_Binder_init);

//调用JNI函数设置Field

env->SetIntField(obj, gBinderOffsets.mObject,(int)jbh);

}


android_os_Binder_init方法的工作可以分成以下两部分:

1)在Native层创建JavaBBinderHolder对象并增加其强引用计数。

2)将该对象的地址存入gBinderOffsets.mObject指定的Java对象的mObject成员变量中。

6.1.1 创建JavaBBinderHolder对象

JavaBBinderHolder定义于frameworks/base/core/jni/android_util_Binder.cpp中,代码如下:


class JavaBBinderHolder:public RefBase

{

public:

sp<JavaBBinder>get(JNIEnv*env, jobject obj)

{

AutoMutex_l(mLock);

sp<JavaBBinder>b=mBinder.promote();

if(b==NULL){

//以Java层传入的系统服务为参数创建Native层的JavaBBinder

b=new JavaBBinder(env, obj);

mBinder=b;

}

return b;

}

sp<JavaBBinder>getExisting()

{

AutoMutex_l(mLock);

return mBinder.promote();

}

private:

Mutex mLock;

wp<JavaBBinder>mBinder;

};


JavaBBinderHolder内部定义了一个JavaBBinder类型的成员变量mBinder,该成员变量是一个wp指针,可以通过get和getExisting方法返回该成员变量的sp指针。因此JavaBBinderHolder是JavaBBinder的持有者(Holder),完全是为了控制JavaBBinder的生命周期而存在的。

注意 RefBase结合sp和wp提供了通过引用计数管理对象生命周期的机制,类似于Java的强引用和弱引用,不同于C++的智能指针。本例中JavaBBinderHolder是RefBase的子类。

到这里JavaBBinderHolder的创建过程就分析完了,接下来分析JavaBBinder。