概述
此文出自笔者回答的一个知乎问题,原问题:
Android Input子系统为什么要使用socket,而不是binder?
Android Input子系统为什么要使用socket,而不是binder?
近期正好学习到Binder与input系统相关的知识,觉得这个问题非常有意思。
使用socket而不使用binder的原因非常多,笔者仅根据自己的认知回答一下,一定会有考虑不周的地方,有想法的读者可以评论补充或者交流。
如果使用binder,会有哪些问题?
- binder与socket相比太耗资源了。
binder通信的逻辑是,每次通信都会去binder线程池里取一个线程,来执行逻辑。binder线程池的大小默认是16,如果不够用还要加线程。与socket”一个场景,一个线程“相比,是不是高下立判? - binder线程池不够用。
使用binder,一个binder线程池对应这个进程的所有binder操作。这意味着整个input系统所有的app进程共用一个binder线程池。(socket会开多个)再加上本身input的场景就是高频操作,你认为binder线程池要设置多大才能满足要求? - binder在高频操作下容易丢事件。
binder在binder线程池超负荷工作的情况时会直接报错,如果用来处理input,那么碰到你在玩王者荣耀高频操作的时候,很可能直接crash,或者出现操作无效的情况。 - 高频的操作必然不会相互依赖,因此binder处理事件没法保证有序。
有序情况下,手机来不及处理,你最多会感觉到卡顿。而一旦无法保证有序,打个比方,你玩游戏使用”左下右“搓了个技能,卡顿了一下,得到的结果是”下左右“。
那么现在使用socket的好处有哪些?
- 保证有序性。
性能不够的时候,最多只是卡一下,不会影响操作结果。 - 除非ANR,一般操作不会丢失。
起码不会”操作越快,越容易游戏崩溃“。 - 节约资源。
每条链路开一个线程,一个socket。和binder搞个线程池相比是不是节约多了? - 双向通信。
其实还是节约资源,一个socket既可以发送也可以接收,使用binder的话,无论哪边发给哪边,每一次通信都需要占有一个线程的资源。