android下Binder机制


以MediaService为例,这个是个后台服务,用来播放多媒体的。

int main(int argc, char** argv)

{

//FT,就这么简单??

//获得一个ProcessState实例

sp<ProcessState> proc(ProcessState::self());

//得到一个ServiceManager对象

    sp<IServiceManager> sm = defaultServiceManager();

    MediaPlayerService::instantiate();//初始化MediaPlayerService服务

    ProcessState::self()->startThreadPool();//看名字,启动Process的线程池?

    IPCThreadState::self()->joinThreadPool();//将自己加入到刚才的线程池?

}


首先明确几个关键问题:
1.android的一个程序(比如activity)的运行机制是这样的:
图形界面的client端,发送请求给服务对应的代理,代理再通过binder(一个驱动),和server端的service通信,service来执行动作。
2.每个service分两个面,service的bnXXX,代理端的bpXXX,bp和bn通过binder通信,bp一般都是把bpbinder对象当做参数传给bpXXX的类,通过bpbinder的transact函数来发送和接受请求(调用 t alkWithDriver与binder设备交互) 。而bn端一般是自己打开binder设备,调用drivertalk函数来发送和接受请求。
3.所有的service都由servicemanager管理,这个servicemanager的名字叫"service”(囧)。它维护着一个链表,里面放了所有的service,用名字(字符串)和对应的对象关联起来。比如代理端要调用mediaservice服务,那就去servicemanager里通过"mediaservice"找这个服务,如果有,就返回一个bpbinder的实例,通过它和service端对话。让service端执行发过去的命令。



上面就是这个service的入口。
第一步的sp<ProcessState> proc(ProcessState::self());就是打开binder
具体做法是:
     1.打开dev/binder设备(android自己创建的虚拟设备,相当于一个文件),得到fd
     2.用mmap把fd映射到内存,映射后的指针保存在ProcessStat的实例中。

第二步:创建一个servicemanager对象。经过几层代码,实际调用的是: interface_cast<IServiceManager>(new BpBinder(0));
bpbinder作为参数传入,作用就是读写binder设备。
关键是另两个:interface_cast函数,和IServiceManager。
interface_cast的作用是以 IServiceManager为接口,生成对应的对象,比如这里就是生成bpServiceM anager对象。
interface_cast<IServiceManager>(new BpBinder(0));等价于 IServiceManager::asInterface(new  BpBinder(0) );所以interface_cast不过是调用 IServiceManager的 asInterface函数,前提是 IServiceManager必须有实现这个函数。

DECLARE_META_INTERFACE(ServiceManager);


IMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager");



IServiceManager类里面通过这两个宏实现了asInterface函数,这种方法借鉴了MFC。
IMPLEMENT_META_INTERFACE (ServiceManager, "android.os.IServiceManager")宏实现的 asInterface函数主要做了下面的事:

new BpServiceManager(obj);

回到前面, interface_cast<IXXX>(new BpBinder(0));的作用就是生成一个bpXXX对象。
BpServiceManager要实现一个函数addservice,这个就是bpServiceManager对象要做的是,添加service,这个函数是在 IServiceManager类里声明的, BpServiceManager通过 class BpServiceManager : public BpInterface<IServiceManager>继承过来。


第三步: MediaPlayerService::instantiate();
new了一个 BnMediaPlayerService ,并调用上面的 bpServiceM anager对象的addservice函数 ,把这个service添加到服务端 bnServiceM anager 管理的list里。
addservice把 BnMediaPlayerService的服务打包成data,再调用bpbinder的transact函数,通过binder设备,把这个包发到服务端的 bnServiceM anager。


第四步:

 ProcessState::self()->startThreadPool();//看名字,启动Process的线程池?

    IPCThreadState::self()->joinThreadPool();//将自己加入到刚才的线程池?

startThreadPool函数创建子线程: _threadLoop,然后调用 joinThreadPool,主线程和子线程都调用了 joinThreadPool。
joinThreadPool函数调用 t alkWithDriver和binder设备交互, executeCommand执行binder中解析出的命令。它是通过BBinder类( MediaPlayerService 的父类),来调用 MediaPlayerService 实现的 onTransact函数,
onTransact会根据不同的指令,执行不同的操作。

下面讲下, MediaPlayerService是怎么实现的

class MediaPlayerService : public BnMediaPlayerService


class BnMediaPlayerService: public BnInterface<IMediaPlayerService>

template<typename INTERFACE>

class BnInterface : public INTERFACE, public BBinder 这里通过模板把要继承的接口IMediaPlayerService,通过多重继承,继承过来


兑现后变成

class BnInterface : public IMediaPlayerService, public BBinder     :这里同时继承了BBinder,后面就可以通过BBinder类,来调用MediaPlayerService实现的函数了




如何自己实现service:

int main()

{

  sp<ProcessState> proc(ProcessState::self());

sp<IServiceManager> sm = defaultServiceManager();

sm->addService(“service.name”,new XXXService());

ProcessState::self()->startThreadPool();

IPCThreadState::self()->joinThreadPool();

}


要实现XXXService,XXXService包括bp和bn两个部分,
要实现bp就要用 class BpXXX: public BpInterface<IXXX>,获取这对象用 inteface_cast<IXXXService>(bpbinder());
要实现bn就要用class bnXXX:public BnInterface<IXXXService>

IXXXService用到下面两个宏:
DECLARE_META_INTERFACE(XXXService);
IMPLEMENT_META_INTERFACE( XXXService , "android.os.I XXXService ");
来实现asInterface,这个用来得到bp对象



同时要定义bp用到函数的虚接口。

bnXXXService继承IXXXService后要定义的接口是onTransact,这个是bn用来处理bp发过来的指令的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值