Android 进阶之跨进程通信(IPC)

孤街醉人 提交于 2020-01-26 00:18:46

先看一下 Android 中跨进程通信的方式:

名称 优点 缺点 使用场景
Intent 简单易用 只能传输 Bundle 所支持的数据类型 四大组件的进程间通信
文件共享 简单易用 不适合高并发 简单的数据共享,无高并发场景
AIDL 功能强大,支持一对多并发实时通信 使用稍微复杂,需要注意线程同步 复杂的进程间调用,Android 中最常用
Messenger 比AIDL稍微简单易用些 比AIDL功能弱,只支持一对多串行实时通信 简单的进程间通信
ContentProvider 强大的数据共享能力,可通过call方法扩展 受约束的AIDL,主要对外提供数据线的CRUD操作 进程间的大量数据共享
RemoteViews 在跨进程访问UI方面有奇效 比较小众的通信方式 某些特殊的场景
Socket 跨主机,通信范围广 只能传输原始的字节流 常用于网络通信中

Binder

Binder 是 Android 系统进程间通信(IPC)方式之一。
参考:
1. Android Bander设计与实现 - 设计篇
2. 图文详解 Android Binder跨进程通信的原理

Messenger

Messenger 是一种轻量级的 IPC 方案并对 AIDL 进行了封装,它实现起来比较容易。
参考:
用Messenger进行进程间通信

AIDL

在 AIDL 文件中支持的数据类型包括:

  • 基本数据类型
  • String和CharSequence
  • List:只支持ArrayList,里面的元素都必须被AIDL支持
  • Map:只支持HashMap,里面的元素必须被AIDL 支持
  • 实现Parcelable接口的对象
  • 所有AIDL接口

参考:
在Android Studio中使用AIDL实现跨进程方法调用

ContentProvider

ContentProvider 为存储和获取数据提供统一的接口,它可以在不同的应用程序之间共享数据,本身就是适合进程间通信的。
参考:
用ContentProvider进行进程间通信

Socket

Socket 也称作“套接字“,是在应用层和传输层之间的一个抽象层,它把TCP/IP层复杂的操作抽象为几个简单的接口供应用层调用以实现进程在网络中通信。
参考:
用Socket实现跨进程聊天程序

文件共享

这种方式解决了不同进程数据传输的问题。
简单实例:
进程a写数据:

Data data = new Data(10,"这是主进程写的数据");
                try {
                    ObjectOutputStream out = new ObjectOutputStream(
                            new FileOutputStream("/storage/emulated/0/1/sina/sdadas.txt"));
                    out.writeObject(data);
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                    Log.d(TAG, "ssss: 序列化的时候失败" + e.toString());
                }

进程b读取数据:

Data data = null;
                try {
                    ObjectInputStream in = new ObjectInputStream(
                            new FileInputStream("/storage/emulated/0/1/sina/sdadas.txt"));
                    data = (Data) in.readObject();
                }catch (IOException e){
                    e.printStackTrace();
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                }

                if(data != null){
                    Log.d(TAG, "onClick: 读取成功 , data.id = "  + data.id + "data.name = " + data.name);
                }else {
                    Log.d(TAG, "onClick: 错误");
                }
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!