桥下红药

机器应该工作、人类应该思考

Binder 跨进程通信机制

Android, 总分类 0 评

Android运行环境就是一个沙盒环境,每当运行一个APP的时候都会有一个独立的进程来运行。进程与进程之间通信方式就叫Binder,接口是 IBinder 。这个东西应用层很少使用到,但是运行过程中无处不在。

直接网上借一张图

粗略的过一遍结构图,Native层也不知道是个什么情况,大约就是 Server端 实现 IBinder 接口,然后把引用注册到 系统服务里,然后 Client 端想要获取 Server 端的数据 就通过某个类 去查找 某个 服务有没有被注册,然后获取到 IBinder 接口 进行通信。(要是真的几句话就说完了里面的细节,怕不是国产操作系统就不是中国梦了,也就雾里看山,模模糊糊看到山的轮廓~)

再稍微凑近点看山

  • 系统里的
    Android系统里提供了一个类叫做 ServiceManagerSystemService , SystemService 是个抽象工厂主要就看2个方法..
publishBinderService(String name, IBinder service,boolean allowIsolated)
getBinderService(String name)

实际这些操作都直接调用的 ServiceManager 里面的addService和getService方法,ServiceManager 又是通过 ServiceManagerNative 完成的。返回BinderProxy代理类。(如果你看过AIDL自动生成的Java接口类会发现里面的代码和ServiceManagerNative非常像)

再看一张图

这张图就非常的能表面情况了,例如我们在调用手机系统里各种功能模块,因为这些都是独立进程的,Java层sdk已经帮我们封装好了操作,例如:

 UsbManager usbManager = (UsbManager) getSystemService(Context.USB_SERVICE);

ContextImpl 的静态代码块中系统默认注册了很多系统服务,如:蓝牙,相机,多用户等等等。所以 getSystemService才获取到。

.....
registerService(USB_SERVICE, new ServiceFetcher() {
            public Object createService(ContextImpl ctx) {
                IBinder b = ServiceManager.getService(USB_SERVICE);
                return new UsbManager(ctx, IUsbManager.Stub.asInterface(b));
            }});
.....

可以看到实质是通过ServiceManager.getService(USB_SERVICE)获取对应的Binder,得到对应的本地代理对象,然后把它封装到UsbManager中,这样最终通过getSystemService就会获取到对应的Manager,这也是为什么我们通过getSystemService可以获取到对应服务的管理者的原因。

总结起来 类 与 类 之间知道用接口回调,进程之间用Binder意思是差不多,只是实现这个机制就是系统帮忙实现了。

补充:Binder驱动使用 内存映射 实现不同进程之前数据同步(传递) , 为什么返回的是BinderProxy?因为不同进程之间不可能真的返回别的进程Object回来,只能构建个和Object方法一样的对象(代理对象),代理对象的方法并没有真的实现逻辑,只是通过Binder去目标进程发送个”消息”,目标进程收到消息 后 再通过Binder返回结果过来。

上一篇

发表评论