1> 这些接口因为需要跨进程调用,因此需要用到binder机制
2>每个接口包括两部分实现,一部分是接口功能的真正实现(BnInterface),这部分运行在接口提供进程中
3>另一部分是接口的proxy(BpInterface),这部分运行在调用接口的进程中
4>sp是android中定义的一个模板类,用于实现智能指针功能。sp就是IMediaPlayer的智能指针
5>binder类包括两个,一个是接口实现类,一个接口代理类。接口代理类继承自BpInterface,接口实现类继承自BnInterface
代理:
1>这些6个枚举定义对应于IMediaPlayerService接口所提供的6个功能函数,可以称为这些功能函数的功能代码,
用于在进程之间进行RPC是标识需要调用哪个函数
2>data.writeInt32(pid);
函数首先向data中写入各种数据。第一个写入的是接口的一个描述字符串,binder的实现类中会用这个字符串来对接口做验证,防止调用错误
3>函数调用remote()->transact()用于完成binder通信。transact()函数的第一个参数就是前面提到过的功能代码。
transact()的功能是将data中的数据传给binder的实现类
4>remote()就是继承自BpRefBase 类的一个成员函数,该函数返回BpRefBase类中定义的一个私有属性mRemote。
mRemote是对IBinder接口类的子类BpBinder 的一个对象的引用
实现
1>BnMediaPlayerService间接继承了IMediaPlayerService接口类。
不过 BnInterface类并没有实现IMediaPlayerService所定义的6个接口函数,
因此BnInterface还是一个纯虚类。这些接口需要在BnMediaPlayerService的子类中真正实现,这个子类就是MediaPlayerService
2>当在代理那边调用了transact()函数后,这边的onTransact()函数就会被调用。
3>case CREATE_URL: {
CHECK_INTERFACE(IMediaPlayerService, data, reply);
pid_t pid = data.readInt32();
sp client = interface_cast(data.readStrongBinder());
const char* url = data.readCString();
sp player = create(pid, client, url);
reply->writeStrongBinder(player->asBinder());
return NO_ERROR;
}
首先是从data对象中依次取出各项输入参数,然后调用接口函数create()(将在子类MediaPlayerService中实现),
最后向reply中写入返回数据。这个函数返回后,代理那边的transact()也会跟着返回。
4>
到这里两个binder类就已经定义完了,下面就是IMediaPlayerService接口函数的真正实现。
前面已经说过这些函数在类 MediaPlayerService中实现。
这个类继承自BnMediaPlayerService,也间接地继承了 IMediaPlayerService接口类定义的6个功能函数,
只需要按照正常方式实现这6个功能函数即可
5>
(三) 总结一下
说了这么多,总结一下。下图是binder机制的层次模型。
如果一个服务需要通过binder机制对外提供跨进程的接口,需要做下面这些事情。
(1) 第一步,需要为这个接口定义一个继承自IInterface的接口类,假设叫做IMyService。
(2) 第二步,需要定义两个binder类,其中一个是代理类BpMyService,需继承自BpInterface;另一个是实现类BnMyService,需继承自BnInterface。
(3) 第三步,定义BnMyService的子类,这个子类可以是任何名字,比如就叫MyService,在其中真正实现接口所提供的各个函数。
(4) 第四步,创建MyService的实例,注册到服务管理器(如IMediaPlayerService),也可以在其它接口的函数中创建(如上面的IMediaPlayer)。
附:Android学习笔记:http://w.baike.com/3fdeadabfa514f1faf372c589632f692.html