以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发过来的指令的。