Android Binder机制中的异步回调

“Binder通信是同步而不是异步的”,但是在实际使用时,是设计成客户端同步而服务端异步。

看看Framwork层的各service类java源码便会知道,在客户端调用服务端的各种方法时,通常会传递一个Binder过来,该Binder对象用于服务端做异步回调,而服务端本身会使用handler或队列的方式做成异步处理。在Android中,系统service是作为"管理者"的身份存在的,像Ams(ActivityManagerService),它并不创建Activity,创建Activity的是客户端的ActivityThread,但是每当ActivityThread想创建一个Acitivty,就必须告诉Ams,Ams会进行调度该Acitivty的创建。更简单的一个例子,Toast和NotificationManagerService,Toast负责弹出窗口的创建显示和隐藏,而何时显示跟何时隐藏却是由NotificationManagerService决定的。具体可以看看这篇文章Toast窗口的源码分析

我们可以发现,当队列本来不为空时,客户端的同步在服务端执行完将ToastRecord放入队列之后就可以结束了。服务端会通过连续取出队列项并且回调客户端的show()和hide()方法。而在服务度回调show()和hide()时,客户端就成了”服务端“,这时它通过handler将本次真正的显示和隐藏Toast窗口操作压入Message队列,再一次实现了异步操作。

那为什么要设计成这样呢?以Toast为例,假如服务端不设计成异步调用+使用Binder回调,那当有2个Toast请求同时过来时,为了实现串行化显示(Toast每次只显示一个,本次显示完毕后才接下去显示下一个),那么第二个Toast进程就必须阻塞着等待第一个Toast显示再隐藏,更糟糕的是,即使是第一个请求也必须在显示之后阻塞着等待服务端发送隐藏指令。

(我在看源码时对于每次IPC调用客户端都会传递一个Binder对象到服务端觉得很奇怪,当时以为是为了"双向通信":服务端也可能需要客户端的一些处理结果。但看了更多代码后我觉得可能更准确的原因是为了异步回调。以上只是个人理解,如有错误请指出。)

转载于:https://www.cnblogs.com/linjzong/p/4143048.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值