Binder学习总结_native(1)

这几天一直在看binder的结构,感叹这样天才的设计。
现在只研究到binder的native框架,在IPCThreadState以下,真正的driver和数据交换还需要进一步研究。在此记录一些目前的体会。

1.IInterface的作用
个人感觉,这个IInterface严格上讲,并不是Binder这个框架的一部分。
它的作用是提供了一个common的方式,可以将IBinder与Service进行显示的转换。
因为在进行IPC时,实际的service IXXXService要转换成IBinder,才能传递给ServiceManager进行注册检索,或者传递给Client进行调用。
而且Client拿到ServiceManager回传的IBinder以后,又要转换回IXXXService进行功能调用,所以IInterface产生了,提供了IXXXService与IBinder互相转换的功能。

(1)IXXXService转换IBinder实现:
IXXXService继承自IInterface,所以IInterface中的asBinder()方法,会将自身,也就是IXXXService转换成一个IBinder对象。
sp IInterface::asBinder()
{
    return this ? onAsBinder() : NULL;
}
这个onAsBinder()是一个虚拟方法,实际上是有IInterface的两个子类BpInterface和BnInterface实现的。
BpInterface的实现:
inline IBinder* BpInterface::onAsBinder()
{
    return remote(); //调用它的父类BpRefBase的remote()方法,返回IBinder,其实就是一个BpBinder
}
BnInterface的实现:
IBinder* BnInterface::onAsBinder()
{
    return this; //就是返回自身,因为BnInterface就是从BBinder继承的,BBinder又是继承自IBinder
}

(2)IBinder转换IXXXService实现:
当一个Client拿到ServiceManager返回的IBinder时,需要转换为IXXXService接口,才能调用它的功能。
这个转换,是由IInterface中定义的宏DECLARE_META_INTERFACE来声明的asInterface完成的,并由宏IMPLEMENT_META_INTERFACE实现的。
将宏代码IMPLEMENT_META_INTERFACE展开后得到:
android::sp I##INTERFACE::asInterface(                
            const android::sp& obj)                   
{                                                                   
    android::sp intr;                                 
    if (obj != NULL) {                                              
        intr = static_cast(                          
            obj->queryLocalInterface( //先调用queryLocalInterface,这个方法是IBinder定义的,默认实现是返回NULL,而在BBinder的子类BnInterface中,重载了该方法,返回this,而
                                      //BpInterface并没有重载,使用IBinder的默认实现,返回NULL。                             
                    IXXXService::descriptor).get());               
        if (intr == NULL)

Unknown macro: {                                                  intr = new BpXXXService(obj); //如果queryLocalInterface返回NULL,就构造一个BpXXXService返回,Client得到的正是这个BpXXXService        }

                                                           
    }                                                               
    return intr;                                                    
}
总结一下,如果传进来的obj参数,是一个BBinder,就返回自身(这种情况应该是service和client在同一进程),如果是一个BpBinder,就new一个代理对象返回(这种情况应该是service和client在不同进程)。                                   

2.IBinder, BBinder和BpBinder
这3个类,是对Android Binder框架的抽象,其实这个BBinder,改成BnBinder可能更形象一些。
但是要注意的是,一个IXXXService的继承图中,BpBinder并不在这个继承关系之中,也就是说BpBinder并没有子类。但是BBinder是在这个继承关系当中的,它的子类就是BnInterface。
换句话说,BBinder和BpBinder的功能并不是对称的,以前就是没有理解到这一点,才会一直很糊涂。

BpBinder的是存在于BpRefBase中的mRemote的成员变量中。从Client调用Service的过程中分析,就更清楚了。
假设有一个IXXXService接口:
class IXXXService : public IInterface {
    ....
    public void helloWorld(const char* str);
    ....
}
(1)client调用service
    client得到一个BpXXXService以后
    (a)会调用BpXXXService实现的helloWorld,它会将str参数打包到Parcel中。然后调用remote()->transact(xxx)
    (b)remote()是在BpXXXService的父类BpRefBase中实现的,返回的就是一个BpBinder.实际上调用的就是BpBinder的transact
    (c)BpBinder的transact实现,就是直接调用IPCThreadState::self()->transact()发送数据。
(2)service接收client请求:
    (a)通过IPCThreadState接收到client的请求后,首先会调用BBinder的transact方法。
    (b)BBinder的transact方法又会调用子类实现的虚拟方法onTransact。这个虚拟方法是在BnXXXService中实现的。
    (c)onTransact方法,会通过传递进来的参数来判断,需要调用IXXXService中的那个方法,示例中只有一个helloWorld方法。
    (d)直接调用helloWorld,就会找到它的真正实现,也就是BnXXXService的子类XXXService中的helloWorld方法。
总结一下,从上面的流程当中就可以看出前文说的,BpBinder并不在继承关系当中,它只是一个打包数据,并通过IPCThreadState::self()->transact()方法发送出去。
而BBinder和BnXXXService的作用,就是接收IPCThreadState传递过来的信息,解包数据,并调用XXXService真正的实现。

IPC的数据处理,Binder Driver和ServiceManager学习后会继续分析总结。


你可能感兴趣的:(Binder)