Android系统--IBinder和BpBinder

IBinder和BpBinder

引言

  1. 总结之前学习的内容可以发现,对于ServiceManager,当想使用其服务的时候,我们首先引入了ServiceManagerProxy,再往上层可以发现是封装了ServiceManager.java以及ServiceManagerNative.java来方便使用。
  2. 在创建ServiceManagerProxy的时候,我们是传入了一个IBinder对象,然后借助其transact方法与Binder驱动进行通信。
  3. 接下来分析一下,IBinder的实现原理

IBinder

  1. IBinder接口当中应当有与Binder一致的接口方法,即实现命令的方法
public boolean transact(int code, Parcel data, Parcel reply, int flags)
        throws RemoteException;

为了获取IBinder对象,必须有一个新的类来获取对象,即BinderInternal,而获取的方法是:

public static final native IBinder getContextObject();

显然在这里也是继续调用native方法,因为最终要与Binder驱动建立关联:

static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
{
    sp b = ProcessState::self()->getContextObject(NULL);
    return javaObjectForIBinder(env, b);
}

可以看到这里利用了ProcessState,调用的是getContextObject方法,而这个方法最终返回的是一个BpBinder对象

BpBinder

  1. IBinder只是一个接口类,在Native层,有BpBInder来继承,在java层有一个Binder.java当中的BinderProxy来实现的。
  2. 当在执行命令的时候,需要将命令通过JNI转换,首先从Java层的Binder当中的BinderProxy开始,一直到JNI当中使用:
IBinder* target = (IBinder*)env->GetLongField(obj, gBinderProxyOffsets.mObject);

来利用getLongField得到BpBinder的内存地址,从而继续调用BpBinder的处理请求函数:

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;
}

可以看到,在这个函数当中仍然是使用了IPCThreadState来进行与Binder驱动的通信。

你可能感兴趣的:(android,system)