第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-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。