概要:
- 多进程开发的应用及其注意点
- 跨进程通信的主要方式以及Binder机制的底层实现
- AIDL Messenger的实现原理(oneway in out inout)
Android多进程:
- 进程是系统资源分配的最小单位,线程是进程内部的独立执行单元是程序执行的最小单位。
- 进程间的资源和数据互相隔离,进程内的线程间共享大多数的资源和数据。
- 进程内可以运行多个线程。线程的崩溃会影响到进程。
使用Android多进程的原因:
- 系统资源紧张OOM
- 应用架构的臃肿(WebView,推送、后台任务)
- 保活黑科技
注意点:
- Application生命周期onCreate
- 数据共享失效(对象、单例、回调)
- 进程间通信(文件、intent、AIDL)
跨进程通信IPC的主要方式:
进程间通过内核提供的机制完成数据交换,就叫:进程间通信IPC(Inter Process Communication)
Android是基于Linux系统。所以需要先了解下Linux系统提供的跨进程通信方式。
Linux系统提供的跨进程通信方式:
- 管道[匿名管道(用于亲缘进程)、有名管道(可用于2个不同的进程)]
管道都是基于内存中的缓冲区来实现。大小是固定的1页=4KB,半双工。
管道在读写时都要确保对端的存在,读只能从头开始读,写只能写入到末尾。
管道中的数据只能向一个方向流动,如果需要双方去进行通信的话,需要建立2个管道,一般管道用于轻量级的进程间通信。
- 消息队列[内核消息链表、多进程读写、随机查询]
消息队列是存放在内核中的消息链表,因为存放在内核中,所以都可以从消息链表中去读和写。
每个消息队列是都有对应的消息队列标识符来表示,消息队列只有在内核重启或特定的删除的情况下才会消失,同时消息队列中的消息写入不需要其他进程再去等待。
- 信号[内核存储发送,软件层次上对于中断机制的模拟]
信号是linux系统中用于进程间相互通信和操作的一种机制。可以在任何时候发送给某个进程而无须知道另外一个进程的状态,如果当前进程处于未执行状态的话,信号就会被内核去保存起来,那个进程告诉它我可以执行了,然后内核才会把存储的信号发送过去。
- 共享内存[IPC中效率最高,需要同步机制]
通过多个进程直接读写同一块内存空间,内核中会专门留一块内存区,可以由需要访问的进程将其映射到自己的私有地址空间,进程就可读写这块内存了而不需要进行数据的拷贝,进而提高了效率。但是由于多个进程共享一段内存,所以需要某种同步机制——信号量
- 信号量:[计数器、进程间同步、PV操作]
信号量其实就是一个计数器,用于多进程对共享数据的访问进行控制。
信号量的意图在于进程间同步,信号量的增减是原子操作,由内核去实现。
- 套接字Socket[C/S结构、跨网络通信]
通过客户端和服务端建立一个Socket的链接,然后完成通信。
Android中跨进程通信核心:
- Binder:
基于C/S架构,稳定性好,优于共享内存,不需要考虑进程间同步的问题。
Binder底层驱动基于内存映射,整体数据拷贝次数为1次,所以性能较好,数据拷贝次数优于管道、消息队列、Socket.
Binder的安全性高,Binder通信的过程中,通信双方的对方的进程的UID/PID可见。
通过编写AIDL去基于BInder提供对外的接口和实现,通过AIDL文件调用到对应的Java层Binder,通过Java层的Binder对象的JNI调用调用到Native层提供的BpBinder和BBinder对象,Native层可以直接去使用BpBinder和BBinder去完成IPC通信,Binder系统的最底层是Kernel内核层,是基于Binder Driver,本质是基于内存的映射。
Binder的应用:
常见的Activity的startService(),其底层是调用到ContextImpl的startService(),其底层又调用到AMSProxy[AIDL层]的startService(),通过AMSProxy的startService()进行Binder IPC调用AMSNative的onTransact(),然后通过它去调用AMS的startService()
Android跨进程通信的方式:
- AIDL(基于Binder):Android官方提供给开发者的能更加方便的实现IPC通信的方式
- Intent、Messenger、ContentProvider(基于AIDL)
- 文件共享
AIDL:
- 定义IPC过程中接口的一种描述语言
- AIDL文件在编译过程中生成接口的实现类,用于IPC通信
- AIDL语法支持基本数据类型,实现Parcelable接口的对象,包括List,Map
Messenger:
- 基于Handler、 Message实现
- 不支持并发的IPC通信,而是串行实时通信
- 能够传输Bundle支持的数据类型
需要掌握的知识点:
- AIDL如何实现IPC
- in out inout关键字的作用
- oneway关键字的作用
- AIDL如何实现Callback
- Messenger的使用和底层实现