您的位置:首页 > 其它

Binder学习总结_native(1)

2014-03-02 14:36 232 查看
http://blog.csdn.net/ljsbuct/article/details/7991838

这几天一直在看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<IBinder> IInterface::asBinder()

{

    return this ? onAsBinder() : NULL;

}

这个onAsBinder()是一个虚拟方法,实际上是有IInterface的两个子类BpInterface和BnInterface实现的。

BpInterface的实现:

inline IBinder* BpInterface<INTERFACE>::onAsBinder()

{

    return remote(); //调用它的父类BpRefBase的remote()方法,返回IBinder,其实就是一个BpBinder

}

BnInterface的实现:

IBinder* BnInterface<INTERFACE>::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<IXXXService> I##INTERFACE::asInterface(                

            const android::sp<android::IBinder>& obj)                   

{                                                                   

    android::sp<IXXXService> intr;                                 

    if (obj != NULL) {                                              

        intr = static_cast<IXXXService*>(                          

            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学习后会继续分析总结。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: