Android Framework下的跨进程通信方式
管道(pipe):半双工,单向的,只能读或者只能写,一般在父子进程间使用。(Looper 4.4版本之前用的管道,后面被替换为eventfd)
Socket:全双工,既可以读也可以写,两个进程之间无需亲缘关系。(zygote使用的是socket)
共享内存:很快,不需要多次拷贝,进程之间无需亲缘关系。(进程之前大数据传输,比如图片,会被使用)
信号:单向的,发出去之后怎么处理是别人的事,只能带个信号,不能带其他参数,知道进程pid就能发信号,而且可以一次给一群进程发信号。
ps:管道与socket都不能传输太大的数据,共享内存可以
Binder
https://www.yuque.com/guoquanliu/big9q9/xm6llbhttps://zhuanlan.zhihu.com/p/35519585
binder是用于通信的,
binder 总共可以分为4个部分:Server、Client、ServiceManager、Binder驱动其中,Server、Client 、ServiceManager是应用层的,Binder驱动是内核层的,ServiceManager是作为Server与Client 之间的桥梁。Binder驱动则是Server、Client、ServiceManager 三者之间的桥梁
binder可以分为2个端,client端与server端。
为什么选择binder作为主要的ipc通讯机制
高效: Binder 数据拷贝只需要一次,而管道、消息队列、Socket都要2次。(管道与socket在数据传输的时候需要从应用层拷贝到内核,内核层拷贝到应用层,这也就意味着有2次数据拷贝,但是binder是可以跨物理内存,同时映射到内核与目标进程的用户空间。)
安全高效: binder机制为每个进程分配了UID/PID 来作为鉴别身份的标示,在binder通信的时候会根据UID/PID 有效行检测 (传统的进程通信方式对通信双方身份并没有作出严格的验证,如Socket通信 ip地址是客户端手动填入,容易出现伪造)
使用简单;采用Client/Server架构,实现面向对象的调用方式
binder对象跨进程传递的原理
binder是怎么跨进程传输的:
(1)Parcel的writeStrongBinder 和readStrongBinder:binder通过parcel进行跨进程传输,通过wirteStrongBinder将parcel写入,并在接收端通过readStrongBinder读出Parcel。
(2)binder在Parcel中存储原理:通过flat_binder_object进行存储,flat_binder_object存储在binder的缓冲区,parcel有个数组专门保存flat_binder_object的偏移,因此在目标进程中,可以根据偏移可以还原出flat_binder_object。
(3) 还原出flat_binder_object后会创建对应的实体对象binder_node,binder_ref(binder的引用对象)
(4) 目标进程根据binder_ref的handle,会创建BpBinder
(5)由BpBinder再往上到BinderProxy到业务层的Proxy
binder的oneway机制
oneway 主要有两个特性:异步调用和串行化处理。
异步调用是指应用向 binder 驱动发送数据后不需要挂起线程等待 binder 驱动的回复,而是直接结束。像一些系统服务调用应用进程的时候就会使用 oneway,比如 AMS 调用应用进程启动 Activity,这样就算应用进程中做了耗时的任务,也不会阻塞系统服务的运行。
串行化处理是指对于一个服务端的 AIDL 接口而言,所有的 oneway 方法不会同时执行,binder 驱动会将他们串行化处理,排队一个一个调用。
带oneway与不带oneway的区别Demo