zoukankan      html  css  js  c++  java
  • 【Android跨进程】IPC总结

    前言

    IPC是Inter-Process Communication的缩写,含义就是进程间通信或者跨进程通信,是指两个进程之间进行数据交换的过程。两个进程可以是两个独立的app也可以是一个app的两个进程。

    跨进程常见的几种通信方式:Bundle通过Intent传递数据,文件共享,ContentProvider,基于Binder的AIDL和Messenger以及Socket。本文主要是做个总结,详细展开会在后续独立成文。

    Android底层是基于Linux,而Linux基于安全考虑,是不允许两个进程间直接操作对方的数据,这就是进程隔离

    在Linux系统中,虚拟内存机制为每个进程分配了线性连续的内存空间,操作系统将这种虚拟内存空间映射到物理内存空间,每个进程有自己的虚拟内存空间,进而不能操作其他进程的内存空间,每个进程只能操作自己的虚拟内存空间,只有操作系统才有权限操作物理内存空间.进程隔离保证了每个进程的内存安全,但是在大多数情形下,不同进程间的数据通讯是不可避免的,因此操作系统必须提供跨进程通信机制。

    一、Intent & Bundle方式

    1. Activity,Service,Receiver 都支持在 Intent 中传递 Bundle 数据,而 Bundle 实现了 Parcelable 接口,可以在不同的进程间进行传输。(四大组件中三大组件)
    2. 在一个进程中启动了另一个进程的 Activity,Service 和 Receiver ,可以在 Bundle 中附加要传递的数据通过 Intent 发送出去。
    private void startWithIntent() {
            Intent intent = new Intent();
            intent.setComponent(new ComponentName("com.owen.stud", "com.owen.stud.intentIpcActivity"));
            //制定要打开的程序的包名和地址(activity名)
            Bundle bundle = new Bundle();//通过budle传递数据,可以携带序列化数据
            bundle.putInt("intextra", 0);
            bundle.putString("stringextra", "");
            intent.putExtras(bundle);
            try {
                startActivity(intent);
            }catch (Exception e){
                ToastUtils.showMessage("没有找到对应文件");
            }
        }

    二、使用文件共享

    1. Windows 上,一个文件如果被加了排斥锁会导致其他线程无法对其进行访问,包括读和写;而 Android 系统基于 Linux ,使得其并发读取文件没有限制地进行,甚至允许两个线程同时对一个文件进行读写操作,尽管这样可能会出问题。
    2. 可以在一个进程中序列化一个对象到文件系统中,在另一个进程中反序列化恢复这个对象(注意:并不是同一个对象,只是内容相同。)。
    3. SharedPreferences 是个特例,系统对它的读 / 写有一定的缓存策略,即内存中会有一份 ShardPreferences 文件的缓存,系统对他的读 / 写就变得不可靠,当面对高并发的读写访问,SharedPreferences 有很多大的几率丢失数据,不那么可靠。因此,IPC 不建议采用 SharedPreferences。

    三、使用 Messenger

    Messenger 是一种轻量级的 IPC 方案,它的底层实现是 AIDL ,可以在不同进程中传递 Message 对象,它一次只处理一个请求,在服务端不需要考虑线程同步的问题,服务端不存在并发执行的情形。

    Messenger是基于AIDL实现的,服务端(被动方)提供一个Service来处理客户端(主动方)连接,维护一个Handler来创建Messenger,在onBind时返回Messenger的binder。

    双方用Messenger来发送数据,用Handler来处理数据。Messenger处理数据依靠Handler,所以是串行的,也就是说,Handler接到多个message时,就要排队依次处理。

    四、使用 AIDL

    Messenger 是以串行的方式处理客户端发来的消息,如果大量消息同时发送到服务端,服务端只能一个一个处理,所以大量并发请求就不适合用 Messenger ,而且 Messenger 只适合传递消息,不能跨进程调用服务端的方法。AIDL 可以解决并发和跨进程调用方法的问题,要知道 Messenger 本质上也是 AIDL ,只不过系统做了封装方便上层的调用而已。

    五、使用 ContentProvider

    用于不同应用间数据共享,和 Messenger 底层实现同样是 Binder 和 AIDL,系统做了封装,使用简单。 系统预置了许多 ContentProvider ,如通讯录、日程表,需要跨进程访问。 使用方法:继承 ContentProvider 类实现 6 个抽象方法,这六个方法均运行在 ContentProvider 进程中,除 onCreate 运行在主线程里,其他五个方法均由外界回调运行在 Binder 线程池中。

    ContentProvider 的底层数据,可以是 SQLite 数据库,可以是文件,也可以是内存中的数据。

    六、使用 Socket

    常用的 Socket 类型有两种:流式 Socket(SOCK_STREAM)和数据报式 Socket(SOCK_DGRAM)。流式是一种面向连接的 Socket,针对于面向连接的 TCP 服务应用;数据报式 Socket 是一种无连接的 Socket ,对应于无连接的 UDP 服务应用。

    Socket 本身可以传输任意字节流。

    谈到Socket,就必须要说一说 TCP/IP 五层网络模型:

    • 应用层:规定应用程序的数据格式,主要的协议 HTTP,FTP,WebSocket,POP3 等;
    • 传输层:建立“端口到端口” 的通信,主要的协议:TCP,UDP;
    • 网络层:建立”主机到主机”的通信,主要的协议:IP,ARP ,IP 协议的主要作用:一个是为每一台计算机分配 IP 地址,另一个是确定哪些地址在同一子网;
    • 数据链路层:确定电信号的分组方式,主要的协议:以太网协议;
    • 物理层:负责电信号的传输。

    Socket 是连接应用层与传输层之间接口(API)。

    只实现 TCP Socket 。

     

     参考:https://github.com/LRH1993/android_interview/blob/master/android/basis/ipc.md#%E4%BA%8C%E4%BD%BF%E7%94%A8%E6%96%87%E4%BB%B6%E5%85%B1%E4%BA%AB

    https://blog.csdn.net/hzw2017/article/details/81275438

  • 相关阅读:
    【Azure 环境】自动化账号生成的时候怎么生成连接与证书
    IntelliJ IDEA 查看类继承关系图,太强大了!
    我们到底为什么要用 IoC 和 AOP
    二叉树、平衡二叉树、红黑树、B树、B+树与B*树
    B-Tree 和 B+Tree傻傻分不清楚
    13K点赞都基于 Vue+Spring 前后端分离管理系统ELAdmin,大爱
    Spring Boot快速开发企业级Admin管理后台
    盘点 Github 上的高仿 app 项目,B站 微博 微信等等
    LeSS 的诞生(一):大规模团队该何去何从
    同事有话说 | 那些所谓的敏捷仪式感
  • 原文地址:https://www.cnblogs.com/ivoo/p/10812103.html
Copyright © 2011-2022 走看看