码迷,mamicode.com
首页 > 编程语言 > 详细

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

时间:2015-06-10 19:30:01      阅读:289      评论:0      收藏:0      [点我收藏+]

标签:

Binder在native层的实现为Binder在java层的实现提供了基石,在java层中,无论是四大组件之间的交互还是使用各种XXXService,都要依靠Binder。而且在java层中,binder的实现同样也还是有四个部分:Client、Proxy、Server、Stub四个部分。下面来看:

6.1Java 系统服务的启动
这里以PowerManagerService为例子,它的启动在init2阶段中的ServiceThread类来启动:
PowerManagerService power = new PowerManagerService();
ServiceManager.addService(Context.POWER_SERVICE, power);
和native层服务的创建和注册类似,也是先启动服务,然后注册到ServiceManager,我们这一节先看启动,下一节看注册到ServiceManager中。
先看PowerManagerService 的继承结构:
技术分享
public class PowerManagerService extends IPowerManager.Stub
 implements LocalPowerManager, Watchdog.Monitor {
这里只关心IPowerManager.Stub,它是IPowerManager的一个内部类,Stub又继承了Binder类。PowerManagerService 的创建调用了其父类所有的构造方法,这里中Binder的构造方法中有一个init方法很重要:
public Binder() {
        init();//native方法
          ...      
    }
 private native final void init();
该init对应的native方法在frameworks/base/core/jni/android_util_Binder.cpp文件中android_os_Binder_init方法:

static void android_os_Binder_init(JNIEnv* env, jobject obj)
{
     //创建JavaBBinderHolder对象并增加strong引用
    JavaBBinderHolder* jbh = new JavaBBinderHolder();  
     jbh->incStrong((void*)android_os_Binder_init);
     //保存jbh的地址到gBinderOffsets.mObject 中
    env->SetIntField(obj, gBinderOffsets.mObject, (int)jbh);
}
做了两个工作: 1 创建JavaBBinderHolder对象并增加strong引用;2 保存jbh的地址到gBinderOffsets.mObject 中
6.1.1 创建JavaBBinderHolder对象并增加strong引用
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) {
           // 以env和obj为参数构建一个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;//定义一个JavaBBinder类型的成员变量mBinder
};
可以看出JavaBBinderHolder是JavaBBinder变量的一个持有者,可以控制JavaBBinder的生命周期。构造JavaBBinder对象,看一下JavaBBinder对象的创建:
class JavaBBinder : public BBinder//继承BBinder
{
public:
    JavaBBinder(JNIEnv* env, jobject object)
        : mVM(jnienv_to_javavm(env)), mObject(env->NewGlobalRef(object))
    {  android_atomic_inc(&gNumLocalRefs);
        incRefsCreated(env);
    }

    bool    checkSubclass(const void* subclassID) const
    {
        return subclassID == &gBinderOffsets;
    }

    jobject object() const
    {
        return mObject;//通过object方法返回mObject成员
    }

protected:
    virtual ~JavaBBinder()
    {
        android_atomic_dec(&gNumLocalRefs);
        JNIEnv* env = javavm_to_jnienv(mVM);
        env->DeleteGlobalRef(mObject);
    }

    virtual status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0)
    {     
         .....
    }         

private:
    JavaVM* const   mVM;
    jobject const   mObject;//这个mObject就是java层传入的系统服务
};
JavaBBinder对象中有一个mObject变量,它保存了java层的系统服务,这里就是PowerManagerService。在java层创建一个服务之后就会在native层创建一个对等的javaBBinder。

6.1.2 保存jbh的地址到gBinderOffsets.mObject
 env->SetIntField(obj, gBinderOffsets.mObject, (int)jbh);函数的作用就是将(int)jbh的值赋值给PowerManagerService中的gBinderOffsets.mObject,那么gBinderOffsets.mObject是什么呢?先看结构体gBinderOffsets:
static struct bindernative_offsets_t
{
    // Class state.
    jclass mClass;
    jmethodID mExecTransact;

    // Object state.
    jfieldID mObject;

} gBinderOffsets;
那现在的问题是gBinderOffsets在哪里初始化的?就在函数register_android_os_Binder函数中:
int register_android_os_Binder(JNIEnv* env)
{
    if (int_register_android_os_Binder(env) < 0)
        return -1;
    if (int_register_android_os_BinderInternal(env) < 0)
        return -1;
    if (int_register_android_os_BinderProxy(env) < 0)
        return -1;
    if (int_register_android_os_Parcel(env) < 0)
        return -1;
    return 0;
}
其中调用了int_register_android_os_Binder函数:
static int int_register_android_os_Binder(JNIEnv* env)
{
    jclass clazz;
   //const char* const kBinderPathName = "android/os/Binder";
    clazz = env->FindClass(kBinderPathName);
  
    gBinderOffsets.mClass = (jclass) env->NewGlobalRef(clazz);
     //对应Binder 类中的boolean execTransact (int,int,int,int)函数
    gBinderOffsets.mExecTransact = env->GetMethodID(clazz, "execTransact", "(IIII)Z");
    //对应Binder类中的int mObject成员变量,因为PowerManagerService继承Binder类,所以有它的变量mObject
    gBinderOffsets.mObject= env->GetFieldID(clazz, "mObject", "I");
  
    return AndroidRuntime::registerNativeMethods(
        env, kBinderPathName,
        gBinderMethods, NELEM(gBinderMethods));
}
可以看出:gBinderOffsets.mObject对应的就是Java中Binder类中的mObject成员变量,这样的话就是将mObject对象设置为JavaBBinderHolder的地址,又因为JavaBBinderHolder中有JavaBBinder,所以就是获取了JavaBBinder对象:
技术分享
这个过程是首先创建一个JavaBBinderHolder对象,该对象中有一个JavaBBinder对象的wp指针(管理JavaBBInder对象的生命周期,),而JavaBBinder中的成员变量mObject保存了Java层的对象,这里就是PowerManagerService对象。JavaBBinder就是PowerManagerService在native层的代表,属于server端
然后将JavaBBinderHolder的地址复制给Binder的mObject变量。这样PowerManager就创建成功,下面看ServiceManager.addService完成注册服务:

6.2 java服务的注册过程
java层也有一个ServiceManager,代码在frameworks/base/core/java/android/os/ServiceManager.java中,直接看addService方法:
    public static void addService(String name, IBinder service) {
        try {
             调用getIserviceManager函数来处理addService方法
            getIServiceManager().addService(name, service);
        } catch (RemoteException e) {
          ...
        }
    }

private static IServiceManager getIServiceManager() {
        //单例模式,只哟一个sServiceManager
        if (sServiceManager != null) {
            return sServiceManager;
        }
        // Find the service manager
        //通过asInterface 方法找到ServiceManager
        sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());
        return sServiceManager;
    }

两个步骤:1 BinderInternal.getContextObject()返回一个IBinder类型的对象;2将IBinder类型的当做参数传递给asInterface函数,返回一个IServiceManager。这个过程和native层中defaultServiceManager类似,分步骤来看:
6.2.1 BinderInternal.getContextObject
先看BinderInternal的getContextObject方法:
 public static final native IBinder getContextObject();//native方法
是一个native方法,对应的native方法在

static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
{
    sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
    return javaObjectForIBinder(env, b);
}
调用ProcessState的getContextObject方法然后返回javaObjectForIBinder,其中ProcessState::self()->getContextObject(NULL);在之前的binder在native实现已经介绍了,它的结果就是返回一个new BpBinder(0)对象。
可以看出java层的ServiceManager使用的是native层servicemanager,在client端的代理都是BpBinder
那么javaObjectForIBinder(env, b);等价于javaObjectForIBinder(env, new BpBinder(0)):

jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val)
{
     //参数val  =new BpBinder(0);
    if (val == NULL) return NULL;
    //1 调用BpBinder的checkSubclass 方法
    if (val->checkSubclass(&gBinderOffsets)) {
        // One of our own!
        jobject object = static_cast<JavaBBinder*>(val.get())->object();         
        return object;
    }

    AutoMutex _l(mProxyLock);

   //2 调用BpBinder对象的findObject方法找到gBinderProxyOffsets 
    jobject object = (jobject)val->findObject(&gBinderProxyOffsets);
    if (object != NULL) { //找到对象
        jobject res = env->CallObjectMethod(object, gWeakReferenceOffsets.mGet);
        if (res != NULL) {          
            return res;
        }        
        android_atomic_dec(&gNumProxyRefs);
        val->detachObject(&gBinderProxyOffsets);
        env->DeleteGlobalRef(object);
    }
     //3 没有找到,创建一个新对象
    object = env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor);
    if (object != NULL) {
      
        // The proxy holds a reference to the native object.
        env->SetIntField(object, gBinderProxyOffsets.mObject, (int)val.get());
        val->incStrong(object);
        
        jobject refObject = env->NewGlobalRef(
                env->GetObjectField(object, gBinderProxyOffsets.mSelf));
        val->attachObject(&gBinderProxyOffsets, refObject,
                jnienv_to_javavm(env), proxy_cleanup);
        
        sp<DeathRecipientList> drl = new DeathRecipientList;
        drl->incStrong((void*)javaObjectForIBinder);
        env->SetIntField(object, gBinderProxyOffsets.mOrgue, reinterpret_cast<jint>(drl.get()));
        
        android_atomic_inc(&gNumProxyRefs);
        incRefsCreated(env);
    }
    return object;
}
三个主要部分:
1 调用BpBInder的checkSubClass方法,如果为true进入判断条件,将BpBInder转换为JavaBBinder并返回。那么BpBinder的checkSubClass的返回值为
bool IBinder::checkSubclass(const void* /*subclassID*/) const
{
    return false;
}
直接返回false,条件不成立。进入第二部分
2 调用BpBinder的findObject方法,参数为gBinderProxyOffsets,实际就是查找3中创建的对象
3 通过一个NewObject方法创建一个Java对象,参数由gBinderProxyOffsets指定。
顺序是3->2,先看3
通过一个NewObject方法创建一个Java对象
其中涉及到一个结构体:
static struct binderproxy_offsets_t
{
    // Class state.
    jclass mClass;
    jmethodID mConstructor;
    jmethodID mSendDeathNotice;

    // Object state.
    jfieldID mObject;
    jfieldID mSelf;
    jfieldID mOrgue;

} gBinderProxyOffsets;
它的初始化在int_register_android_os_BinderProxy函数中完成:
static int int_register_android_os_BinderProxy(JNIEnv* env)
{
    jclass clazz;
   
    clazz = env->FindClass("java/lang/ref/WeakReference");
    //mClass 变量指向java/lang/ref/WeakReference 
    gWeakReferenceOffsets.mClass = (jclass) env->NewGlobalRef(clazz);
     //mGet 指向WeakReference 中的Object get()方法
    gWeakReferenceOffsets.mGet= env->GetMethodID(clazz, "get", "()Ljava/lang/Object;");
 
    clazz = env->FindClass("java/lang/Error");
     //mClass 变量指向java/lang/Error 
    gErrorOffsets.mClass = (jclass) env->NewGlobalRef(clazz);

     //const char* const kBinderProxyPathName = "android/os/BinderProxy";
    clazz = env->FindClass(kBinderProxyPathName);
    //mClass 变量指向  android/os/BinderProxy 
    gBinderProxyOffsets.mClass = (jclass) env->NewGlobalRef(clazz);
         //mConstructor变量指向  android/os/BinderProxy  的void <init>函数
    gBinderProxyOffsets.mConstructor= env->GetMethodID(clazz, "<init>", "()V");
    //mSendDeathNotice 指向void sendDeathNotice(android.os.IBInder.DeathRecipient)方法 
    gBinderProxyOffsets.mSendDeathNotice= env->GetStaticMethodID(clazz, "sendDeathNotice", "(Landroid/os/IBinder$DeathRecipient;)V");
    //  mObject指向 int mObject
    gBinderProxyOffsets.mObject= env->GetFieldID(clazz, "mObject", "I");
     // mSelf 指向WeakReference mSelf
    gBinderProxyOffsets.mSelf= env->GetFieldID(clazz, "mSelf", "Ljava/lang/ref/WeakReference;");   
     //mOrgue 指向int mOrgue
    gBinderProxyOffsets.mOrgue= env->GetFieldID(clazz, "mOrgue", "I");
    
    clazz = env->FindClass("java/lang/Class");
     //mGetName  指向string getName()方法
    gClassOffsets.mGetName = env->GetMethodID(clazz, "getName", "()Ljava/lang/String;");
   
    return AndroidRuntime::registerNativeMethods(
        env, kBinderProxyPathName,
        gBinderProxyMethods, NELEM(gBinderProxyMethods));
}

再看3中通过gBinderProxyOffsets创建对象
gBinderProxyOffsets.mClass指向 android.os.BinderProxy 
mConstructor变量指向  android.os.BinderProxy  的void <init>函数


 //3 没有找到,创建一个新对象
    object = env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor);//就是创建一个BinderProxy对象
    if (object != NULL) {
      
        // The proxy holds a reference to the native object.
        //将BpBinder的值引用存储到BinderProxy 的mObject 变量中
        env->SetIntField(object, gBinderProxyOffsets.mObject, (int)val.get());
        val->incStrong(object);//增加BpBinder的引用
        //mSelf变量 指向BinderProxy 中类型为WeakReference mSelf        
       //再创建一个WeakReference mSelf   全局引用
        jobject refObject = env->NewGlobalRef(env->GetObjectField(object, gBinderProxyOffsets.mSelf));
        //创建的BinderProxy对象的弱引用存入到BpBinder中
        val->attachObject(&gBinderProxyOffsets, refObject, jnienv_to_javavm(env), proxy_cleanup);        
     ......
    }
3的流程创建BinderProxy对象,并将BpBinder存入到BinderProxy的mObject变量之中,并增加BpBinder的引用计数,最后调用attachObject将BinderProxy的weakReference存入到BpBinder对象中。
如果下一次调用javaObjectForIBinder,就会进入2的流程:返回BpBinder中的BinderProxy弱引用,并调用detachObject从BpBinder中删除该弱引用,然后进入3的流程。
javaObjectForIBinder将BpBinder与BinderProxy关联起来,然后返回BinderProxy对象,也就是BinderInternal.getContextObject返回的就是BinderProxy对象。BinderProxy对应着native层的BpBinder。

6.2.2 asInterface
ServiceManagerNative.asInterface(BinderInternal.getContextObject());就等价于
ServiceManagerNative.asInterface(new BinderProxy());
看ServiceManagerNative的asInterface函数:
 static public IServiceManager asInterface(IBinder obj)
    {
        if (obj == null) {
            return null;
        }
        IServiceManager in =
            (IServiceManager)obj.queryLocalInterface(descriptor);
        if (in != null) {
            return in;
        }
        //如果没有创建,则创建一个ServiceManagerProxy(obj) 
        return new ServiceManagerProxy(obj);
    }
ServiceManagerProxy实现IServiceManager接口,内部有一个IBinder成员变量,它的结构:
技术分享

ServiceManagerProxy 类在ServiceManagerNative.java中
class ServiceManagerProxy implements IServiceManager {
    public ServiceManagerProxy(IBinder remote) {//我们在构造的时候remote是BinderProxy类型的
        mRemote = remote;
    }
    
    //通过asBinder函数返回mRemote变量
    public IBinder asBinder() {
        return mRemote;
    }
    //实现了getService 、checkService 、addService 、listServices 等方法
    public IBinder getService(String name) throws RemoteException {
      ...
    }

    public IBinder checkService(String name) throws RemoteException {
      ...
    }

    public void addService(String name, IBinder service)
            throws RemoteException {
       ...
    }
   
    public String[] listServices() throws RemoteException {
     ...
     
    }

    public void setPermissionController(IPermissionController controller)
            throws RemoteException {
    ....
    }

    private IBinder mRemote;
}
创建的ServiceManagerProxy就是讲BinderProxy类型的remote参数存入到mRemote中,并通过asBinder方法返回该BinderProxy对象,所以ServiceManagerNative.asInterface的作用就是创建一个ServiceManagerProxy对象,该对象的mRemote变量存入BinderProxy对象,BinderProxy对象又对应着native层的BpBinder对象。


6.2.3 ServiceManagerProxy.addService添加服务
到此为止getIServiceManager方法返回的就是一个ServiceManagerProxy的对象,那么ServiceManager.addService就是调用ServiceManagerProxy的addService方法来实现:
 public void addService(String name, IBinder service)
            throws RemoteException {
         //name为"power",service 为PowerManagerService对象
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IServiceManager.descriptor);
        data.writeString(name);
         //将PowerManagerService对象 写入到Parcel
        data.writeStrongBinder(service);
         //利用BinderProxy对象的transact方法进行IPC通信
        mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);
        reply.recycle();
        data.recycle();
    }
两个关键步骤:  1 writeStrongBinder(PowerManagerService) ;2 BinderProxy.transact进行IPC

 1 writeStrongBinder(PowerManagerService)
向Parcel类型对象中写入IBinder类型的数据,它是一个本地方法,实现在frameworks/base/core/jni/android_os_Parcel.cpp中
android_os_Parcel_writeStrongBinder方法:

static void android_os_Parcel_writeStrongBinder(JNIEnv* env, jclass clazz, jint nativePtr, jobject object)
{
    //将java层的Parcel对象转换为native层的parcel对象
    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
    if (parcel != NULL) {
         //ibinderForJavaObject得到PowerManagerService中的JavaBBinder对象         //利用writeStrongBinder将JavaBBinder写入parcel
        const status_t err = parcel->writeStrongBinder(ibinderForJavaObject(env, object));
        if (err != NO_ERROR) {
            signalExceptionForError(env, clazz, err);
        }
    }
}
重要的方法是ibinderForJavaObject方法,它在android_util_Binder.cpp文件中:
sp<IBinder> ibinderForJavaObject(JNIEnv* env, jobject obj)
{
    //obj为PowerManagerService
    if (obj == NULL) return NULL;
    //PowerManagerService是Binder的子类,条件成立    if (env->IsInstanceOf(obj, gBinderOffsets.mClass)) {
        //取出之前存放在Binder.mObject中的jbh地址
        JavaBBinderHolder* jbh = (JavaBBinderHolder*)env->GetIntField(obj, gBinderOffsets.mObject);
        return jbh != NULL ? jbh->get(env, obj) : NULL;
    }

    if (env->IsInstanceOf(obj, gBinderProxyOffsets.mClass)) {
        return (IBinder*)env->GetIntField(obj, gBinderProxyOffsets.mObject);
    }
    return NULL;
}
因为obj类型是PowerManagerService,它是Binder的子类,所以进入第一个条件,并调用JavaBBinderHolder的get方法,看一下该方法的实现:
  sp<JavaBBinder> get(JNIEnv* env, jobject obj)
    {
        AutoMutex _l(mLock);
        sp<JavaBBinder> b = mBinder.promote();
        if (b == NULL) {
            b = new JavaBBinder(env, obj);
            mBinder = b;         
        }
        return b;
    }
实际就是返回JavaBBinder类型变量,ibinderForJavaObject就是返回了在创建PowerManagerService时创建的JavaBBinder对象。

2 BinderProxy.transact进行IPC
BinderProxy中的transact方法是一个本地方法,对应的native实现方法在android_util_binder.cpp的android_os_BinderProxy_transact方法
static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj,jint code, jobject dataObj,
                                                jobject replyObj, jint flags)
{
   //参数:ADD_SERVICE_TRANSACTION, data, reply, 0 
       
    Parcel* data = parcelForJavaObject(env, dataObj);//java中的parcel类型转换为native层的parcel类型
     ..
    Parcel* reply = parcelForJavaObject(env, replyObj);//java中的parcel类型转换为native层的parcel类型 
    ..
    //获取BinderProxy中的mObject ,mObject存储的是BpBinder
    IBinder* target = (IBinder*)env->GetIntField(obj, gBinderProxyOffsets.mObject);//获取BinderProxy中的mObject
   ...
     //调用BpBinder的transact的方法 
    status_t err = target->transact(code, *data, reply, flags);
    ...    
    return JNI_FALSE;
}
实际调用BpBinder上的transact方法:

status_t BpBinder::transact(
    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
    // Once a binder has died, it will never come back to life.
    if (mAlive) {
        status_t status = IPCThreadState::self()->transact(
            mHandle, code, data, reply, flags);
        if (status == DEAD_OBJECT) mAlive = 0;
        return status;
    }

    return DEAD_OBJECT;
}
这部分功能就和native通信一样了,不做介绍了,请看binder在native层的实现


6.3 Client获取服务代理
上面介绍的都是PowerManagerService的创建和注册,下面介绍Client如何使用该service.
在sdk层使用系统服务时都是使用context.getSystemService(ServiceName)的方式,getSystemService的具体实现在ContextImpl文件中:
    @Override
    public Object getSystemService(String name) {
        ServiceFetcher fetcher = SYSTEM_SERVICE_MAP.get(name);
        return fetcher == null ? null : fetcher.getService(this);
    }
SYSTEM_SERVICE_MAP是一个Hashmap结果,以servicename为键,ServiceFetcher类型 为value。SYSTEM_SERVICE_MAP的初始化在ContextImpl的static代码块中由registerService方法来实现:
 private static void registerService(String serviceName, ServiceFetcher fetcher) {
        if (!(fetcher instanceof StaticServiceFetcher)) {
            fetcher.mContextCacheIndex = sNextPerContextServiceCacheIndex++;
        }
        SYSTEM_SERVICE_MAP.put(serviceName, fetcher);
    }
对于PowerManagerService来说就是:
 registerService(POWER_SERVICE, new ServiceFetcher() {
                public Object createService(ContextImpl ctx) {
                    //通过getService方法回去一个IBinder对象
                    IBinder b = ServiceManager.getService(POWER_SERVICE);
                    //利用asInterface,将IBinder转换为IPowerManager
                    IPowerManager service = IPowerManager.Stub.asInterface(b);
                    //构造一个PowerManager
                    return new PowerManager(service, ctx.mMainThread.getHandler());
                }});
关键工作在createService中,一共有步骤:
1 通过getService方法回去一个IBinder对象
2 利用asInterface,将IBinder转换为IPowerManager
3 构造一个PowerManager

6.3.1 通过ServiceManager.getService获取BinderProxy
看ServiceManager.getService函数:    /**
     * Returns a reference to a service with the given name.
     *
     * @param name the name of the service to get
     * @return a reference to the service, or <code>null</code> if the service doesn‘t exist
     */
    public static IBinder getService(String name) {
        try {
            IBinder service = sCache.get(name);//该service在mCache中是否存在
            if (service != null) {//一开始sCache为null,所以不存在该service
                return service;
            } else {               
                //否则直接调用getIServiceManager().getService(name) 
                return getIServiceManager().getService(name);
            }
        } catch (RemoteException e) {
            Log.e(TAG, "error in getService", e);
        }
        return null;
    }
getIServiceManager()的返回值就是ServiceManagerProxy,等价于ServiceManagerProxy.getService(serviename),直接看该函数的实现,在ServiceManagerNative.java文件中:    
    public IBinder getService(String name) throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IServiceManager.descriptor);
        data.writeString(name);
        //mRemote就是BinderProxy,对应native层的BpBinder(0),进行IPC通信
        mRemote.transact(GET_SERVICE_TRANSACTION, data, reply, 0);
        IBinder binder = reply.readStrongBinder();
        reply.recycle();
        data.recycle();
        return binder;
    }
其中 mRemote.transact过程上面已经介绍过,来看reply.readStrongBinder()函数,它是一个native函数,对应的native函数实现在android_os_Parcel.cpp的android_os_Parcel_readStrongBinder()函数:
static jobject android_os_Parcel_readStrongBinder(JNIEnv* env, jclass clazz, jint nativePtr)
{
    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
    if (parcel != NULL) {
        return javaObjectForIBinder(env, parcel->readStrongBinder());
    }
    return NULL;
}
又是调用了javaObjectForIBinder函数,前面已经分析过了,它是将java层的BinderProxy和native层的BpBinder关联,这里关联的是服务的BinderProxy

6.3.2 利用asInterface,将IBinder转换为IPowerManager
直接调用 IPowerManager.Stub.asInterface(b);
public static IPowerManager asInterface(IBinder obj)
        {
 
            if(obj == null)
                return null;
            IPowerManager in = (IPowerManager)obj.queryLocalInterface("android.os.IPowerManager");
            if(in != null)//in==null
                return in;
            else//进入到这里,创建Proxy对象
                return new Proxy(obj);
}



 private static class Proxy
            implements IPowerManager
        {

   private IBinder mRemote;
    Proxy(IBinder remote)
            {
 
                mRemote = remote;   
             }


  public IBinder asBinder()
            {
 
                return mRemote;
     
               }          
}

在proxy的成员变量mRemote中存储了BinderProxy对象,BinderProxy又存储了BpBinder对象,因为proxy可以和server进行通信,同时又实现了IPowerManager接口,所以client可以通过这个Proxy来访问Server端的方法。

6.3.3 构造PowerManager
因为IPowerManager.Stub.Proxy没有公开,我们没法使用,如果要使用的话通过相应PowerManager来访问:
public class PowerManager{
public PowerManager(IPowerManager service, Handler handler)
    {
        mService = service;
        mHandler = handler;
    }

     public boolean isScreenOn()
    {
        try {
            return mService.isScreenOn();
        } catch (RemoteException e) {
            return false;
        }
    }
     ...其他方法

    IPowerManager mService;//proxy的引用
    Handler mHandler;
}
}


6.4 client调用powerManagerService的方法
到目前为止,我们还没有调用powermanagerservice提供的服务,这里以isScreenOn方法为例,我们调用的时候使用的是PowerManager的isScreenOn方法:
   public boolean isScreenOn()
    {
        try {
            return mService.isScreenOn();
        } catch (RemoteException e) {
            return false;
        }
    }
而mService就是传入的Proxy对象,再调用Proxy的isScreenOn方法,它调用mRemote.transact(Stub.TRANSACTION_isScreenOn,data,reply)方法,之后进入BpBinder的transact方法,然后该命令转发给BBinder的transact方法,进而调用onTransact方法处理,onTransact的由JavaBBinder的onTransact来处理:

    virtual status_t onTransact(
        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0)
    {
        JNIEnv* env = javavm_to_jnienv(mVM);

        IPCThreadState* thread_state = IPCThreadState::self();
        const int strict_policy_before = thread_state->getStrictModePolicy();
        thread_state->setLastTransactionBinderFlags(flags);
     //执行java层中Binder类中的exeTransact方法:
        jboolean res = env->CallBooleanMethod(mObject, gBinderOffsets.mExecTransact,
            code, (int32_t)&data, (int32_t)reply, flags);
        jthrowable excep = env->ExceptionOccurred();

        return res != JNI_FALSE ? NO_ERROR : UNKNOWN_TRANSACTION;
    }
调用了Binder类中的EXETransact方法:

    // Entry point from android_util_Binder.cpp‘s onTransact
    private boolean execTransact(int code, int dataObj, int replyObj,
            int flags) {
        Parcel data = Parcel.obtain(dataObj);
        Parcel reply = Parcel.obtain(replyObj);
        // theoretically, we should call transact, which will call onTransact,
        // but all that does is rewind it, and we just got these from an IPC,
        // so we‘ll just call it directly.
        boolean res;
        try {
            res = onTransact(code, data, reply, flags);
        } catch (RemoteException e) {
            reply.writeException(e);
            res = true;
        } catch (RuntimeException e) {
            reply.writeException(e);
            res = true;
        } catch (OutOfMemoryError e) {
            RuntimeException re = new RuntimeException("Out of memory", e);
            reply.writeException(re);
            res = true;
        }
        reply.recycle();
        data.recycle();
        return res;
    }


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

标签:

原文地址:http://blog.csdn.net/yujun411522/article/details/46444869

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!