无冥冥之志者,无昭昭之明;无惛惛之事者,无赫赫之功。
解释:没有专心致志地刻苦学习,就没有融会贯通的智慧;没有埋头执着的工作,就不会取得显著的成就。
问题:谈谈对Binder的理解?
Binder是Android中非常重要的进程间通信机制。可以从以下几个方面讲。
一、使用Binder的好处
使用Binder的好处有三个:1、高效性,Binder使用mmap进行内存映射,使得在进程间通信的时候数据只需要在用户空间和内核空间进行一次拷贝。2、稳定性,Binder使用C/S架构模式,Client和Server是两个独立的进程,相互之间影响较小,比较稳定。3、安全性,Binder在进程间通信时可以传递进程的UID和PID信息,这样另一方可以通过这些信息进行安全检验。
二、Binder的使用方式
Binder的使用场景在Android中非常的多,但是平常开发中多是以AIDL来实现。AIDL实现的步骤: 1、创建AIDL文件 2、创建一个Service继承AIDL生成的Binder的Server端,实现相应的功能 3、创建Activity,通过bindService的方式绑定前面创建的Service。
三、Binder进程间通信在Android的分类
Binder在Android中的通信方式我认为有两种,一种是在ServiceManager中注册的,一种是在需要通信的时候直接建立起联系的。
1、需要在ServiceManager中注册的
这种方式需要介绍一下ServiceManager。ServiceManager运行在一个独立的进程中,这个进程又init进程拉起。ServiceManager进程起来之后做三个事情:(1)、打开Binder驱动,也就是/dev/binder文件,在驱动层生成一个进程节点(proc_node)。(2)、调用become_comtext_mgr,成为Binder上下文管理者,这样做的用处是后续Android系统中不管哪里想要获得ServiceManager的远程代理对象都可以通过句柄0(handle=0)来获取。(3)、将ServiceManager进程的主线程设置成Binder线程,同时进入循环等待状态,等待注册或者查询服务的请求到来。
基于这种方式的Binder进程间通信方式,Server端需要事先在ServiceManager中注册。Client端想要某个Server的服务能力需要向ServiceManager查询这个Server。
2、直接建立联系方式
基于这种方式的Binder进程间通信,在Client与Server联系的时候,Client将自己的Binder本地对象经过Binder驱动传递给Server(需要注意的是,经过Binder驱动之后,Server收到的是Client端的Binder的远程代理对象)。这种情况就像在启动应用程序的时候,在ActivityThread的attach方法中,应用程序讲一个ApplicationThread对象传递给AMS,之后AMS就可以通过这个对象跟应用程序通信了。
四、Binder进程间通信的注意事项
1、Binder进程间通信,不管是在Client或者是Server端,都是在Binder线程中处理的,所以通信后需要涉及主线程处理的话需要使用Handler等。
2、Binder进程间通信最多只能传递1016k的数据,超过这个大小的数据会报错并且Crash。
3、同一个应用中,startActivity中的Intent参数使用了Bundle的话需要注意数据的大小。这种数据传递数据大小也要小于1016k。
4、默认情况下,一个应用程序启动之后,就会启动Binder线程池,这里面一般只有一个Binder线程,如果不够一般Binder驱动会通知新增。