从setPhoneState的调用过程中学习C++版Binder的用法

1.先从调用者说起

AudioSystemsetPhoneState中:

aps->setPhoneState(state),

aps类型:

sp<IAudioPolicyService>

2.IAudioPolicyService是一个抽象类,找子类,共两位

BnAudioPolicyServicepublic BnInterface<IAudioPolicyService>

BpAudioPolicyServicepublic BpInterface<IAudioPolicyService>

3.BnInterfaceBpInterface是什么鬼?

原来是C++模板类

template<typenameINTERFACE>

class BnInterface :public INTERFACE。。。

class BpInterface :public INTERFACE。。。

当前的情况尖括号里是IAudioPolicyService

所以上面这个就相当于classBnInterface : public IAudioPolicyService

也就是说BnInterfaceBpInterface都是继承自IAudioPolicyService


4.调用者AudioSystem调用之后需要找实现,那真实调用的setPhoneState的实现,就在BnAudioPolicyService,BpAudioPolicyService这两者中间,很明显,BnAudioPolicyService没实现任何来自爷爷类IAudioPolicyService的成员函数,但是BpAudioPolicyService中是有实现的,

virtual status_tsetPhoneState(audio_mode_t state)

{

Parcel data,reply;

data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());

data.writeInt32(state);

remote()->transact(SET_PHONE_STATE, data, &reply);

returnstatic_cast <status_t> (reply.readInt32());

}

6.BnAudioPolicyService实现了来自爸爸的onTransact函数。函数的实现就是根据各种code做一些对应的操作,比如setPhoneState对应的:

caseSET_PHONE_STATE: {

CHECK_INTERFACE(IAudioPolicyService, data, reply);

reply->writeInt32(static_cast <uint32_t>(setPhoneState(

(audio_mode_t) data.readInt32())));

returnNO_ERROR;

} break;

这就很明显,又很关键了,

一个transact,一个onTransact,一发一收,一唱一和,就用一个码来完成通信。


7.onTransact里很明显调用了setPhoneState()方法,而这个类本身并没有实现setPhoneState(),所以往下找,找它的子类吧

AudioPolicyServicepublic BnAudioPolicyService

AudioPolicyService中:(实现在AudioPolicyInterfaceImp.cpp中,惊讶!)

mAudioPolicyManager->setPhoneState(state);

虽然可能你已经很兴奋地要喊出来了,实现就在AudioPolicyManager中,但是请别着急!

请看:

AudioPolicyInterface*mAudioPolicyManager;

这个变量的赋值根本不在AudioPolicyInterfaceImp.cpp中,害我找了好几分钟,AudioPolicyService类的实现,除了AudioPolicyInterfaceImp.cpp文件,还有个纯正的AudioPolicyService.cpp。作者请给我打电话跟我解释一下这件事情,是不是有毛病?

mAudioPolicyManager= createAudioPolicyManager(mAudioPolicyClient);

这行代码出自voidAudioPolicyService::onFirstRef()

是不是明白什么了,我擦,开机启动时mediaserver直接会启动AudioPolicyAudioFlinger两大服务。这个变量在时候被初始化了!


8.上面说到的这个createAudioPolicyManager函数又是一个”虚“函数,给人一种无处不在的赶脚。这样就能让各家手机厂商,芯片厂商自己实现自己的AudioPolicyManager了。总之我们知道这时候函数调用进入到了AudioPolicyManger里就好了。再往下扯,各位看官又该吐槽我写的东西又长又臭了,而且还离题千里。


9.话说前面说到BnAudioPolicyService,BpAudioPolicyService这两货一唱一和就实现了Binder调用。在我展开说之前你肯定也像第一次看的我一样不信。实现就在同一个文件里。直接调用不就完了吗?为嘛非得通过这种transact,onTransact的方式呢?

你别忘了现在讲的是Binder.应用场景是跨进程的。也就是说BnAudioPolicyServiceBpAudioPolicyService代码文件写在同一个文件里是方便你看,其实他们运行的时候完全是两个进程。BnAudioPolicyService咱们前面分析过了,真正的实现在服务端,mediaserver进程。BpAudioPolicyService是什么进程呢?取决与调用者,AudioSystem的调用者。全局搜索一下,不难发现,来自java层的AudioSystem类通过jni调用过来(我说的是setPhoneState函数,不是所有),最终能追述到AudioService。而对应到用户端能掉用的就是AudioManager接口了。


10.把废话整理一下,就是第三方应用通过AudioManager层层调用的一个函数,通过Binder调用到mediaserver进程中实现的函数。正所谓跨进程啦。


11.至于中间这个binder是怎么通过code进行调用的呢?

binder又是一个进程了,一个服务进程。你想想你在淘宝上买东西的时候,是不是淘宝给你送货的?都是快递帮你们进行转发的。也许binder就是一个送快递的呢!哈哈

具体细节我也不知道呢,毕竟,本文的标题是用法,而不是原理!!!hahaha


原理请看:

http://blog.csdn.net/coding_glacier/article/details/7520199

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值