iis服务器助手广告广告
返回顶部
首页 > 资讯 > 移动开发 >【IPC】Android中的进程间通信(IPC)详解
  • 603
分享到

【IPC】Android中的进程间通信(IPC)详解

进程ipc进程间通信通信Android 2022-06-06 13:06:24 603人浏览 泡泡鱼
摘要

1 需要的知识点 1.1 进程与线程 要理解跨进程通信,首先需要理解以下几个知识点1: 进程:按照操作系统的描述,进程是资源分配的最小单位,一个

1 需要的知识点 1.1 进程与线程

要理解跨进程通信,首先需要理解以下几个知识点1:

进程:按照操作系统的描述,进程是资源分配的最小单位,一个进程可以包含多个线程 线程:线程是CPU调度的最小单位,多线程需要考虑并发问题。 1.2 Android中的多进程

Android多进程指的是一个应用中存在多个进程的情况,在Android中,一般一个应用存在一个进程。多进程的情况2:

某个应用由于自身原因需要采用多进程模式实现 为了加大一个应用可使用的内存,通过多进程来获取多份内存空间

开启多进程模式是通过在

AndroidManifest
中指定
Android:process
属性


“:”
开头的进程属于应用的私有进程,其它应用的组件不可以与它跑在同一个进程中,而不以冒号开头的数据全局进程,其它应用通过
shareUID
方式可以和它跑在同一个进程中。
shareUID
:Android系统会为每个程序分配一个不同级别的UID,如果需要相互调用,只能是UID相同才行,这就使得共享数据具有了一定的安全性,每个软件之间是不能随意获得数据的,而同一个Application只有一个UID,所以Application之间不存在访问权限的问题。

一般来说,使用多进程会存在以下几个问题:

静态成员与单例模式完全失效 线程同步机制完全失效 SP(SharedPreference)可靠性会下降 Application创建多次 1.3 数据共享方法

如果你需要做一个

Application
将某些服务的
Service
Provider
或者
Activity
等的数据共享出去,有如下三个办法:

完全暴露 :使用
android:exported="true"
,一旦设置了
true
,则将会被完全暴露,可以被其它应用进程调用其暴露出去的数据。没有使用
android:exported
Service
Provider
或者
Activity
,其默认的
exported
值为
false
,但此时如果设置了
intent filter
,则其默认值为true. 权限提示暴露:如果应用A设置了
android:permission="xxx.xxx.xxx"
,则你必须在Manifest中使用
use-permission
才能访问应用A的东西。 私有暴露:假如说一个公司做了两个产品,只想这两个产品之间可互相调用,那么这个时候就必须使用
shareUserID
将两个软件的Uid强制设置为一样的。这种情况下必须使用具有该公司签名的签名文档才能,如果使用一个系统自带软件的
ShareUID
,例如Contact,那么无须第三方签名。3 1.4 IPC基础概念介绍

Serialiazable
Parcelable

序列化:讲对象转化为字节的过程
Serialiazable
:Java提供的序列化接口
Parcelable
:Android提供的序列化接口

Serialiazable
Parcelable
的区别
Serialiazable
使用简单但是需要大量I/O操作,
Parcelable
使用较繁琐,主要用于内存序列化,效率高。

Binder

详见【IPC】Binder跨进程通信机制原理

2 实现IPC方式

实现IPC方式可以分为以下几种方式4:

使用
Bundle
使用文件共享 使用
SharedPreferences
使用
Messenger
使用
aiDL
使用
ContentProvider
使用
Binder
连接池 Broadcast Socket 管道 2.1 使用Messenger

Messenger
被称为信使,常与
Message
一起使用实现跨进程通信。底层只是对
Binder
的简单包装

步骤 创建一个
Service
,在
Service
中的
onBind
里返回一个
IBinder
对象。 在
AndroidManifest
中声明服务,并将该服务放在另外的一个进程中 通过
bindService
绑定服务 在客户端创建
ServiceConnection
对象,使用服务端返回的
IBinder
对象创建一个
Messenger
,该
Messenger
是服务端的
Messenger
,可以通过该
Messenger
将客户端数据发送到服务端(该方法是通过客户端向服务端传递数据,如果想从服务端向客户端传递数据,可以通过在客户端创建一个
Handler
对象,然后通过该对象创建一个客户端
Messenger
,然后通过
message.replyTo
5将客户端的
Messenger
发送到服务端,然后在服务端获取客户端创建的
Messenger
,然后通过Messenger将数据发送给客户端,这样就实现了服务端向客户端传递数据) 通过
mMessenger.send(message)
来将数据发送给服务端,从而实现跨进程通信。 代码实现
创建一个
Service
,在
Service
中的
onBind
里返回一个
IBinder
对象。

public class MessengerService extends Service {
    //服务端自己的信使,为了获取客户端数据
    private Messenger mMessenger;
    //客户端信使对象,为了将数据发送到客户端
    private Messenger cMessenger;
    @Override
    public IBinder onBind(Intent intent) {
        mMessenger = new Messenger(new MyHandler());
        System.out.println("MessengerService onBind");
        return mMessenger.getBinder();
    }
    class MyHandler extends Handler{
        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
            switch (msg.what){
                case 0:
                    Message message = Message.obtain(null,1);
                    message.arg1 = 1000;
                    //获取客户端传递来的信使
                    cMessenger = msg.replyTo;
                    try {
                        //通过客户端信使发送服务端数据到客户端
                        cMessenger.send(message);
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }
                    System.out.println("MessengerService handleMessage");
                    break;
            }
        }
    }
}

AndroidManifest
中声明服务,并将该服务放在另外的一个进程中


使用Messenger实现客户端和服务端双向通信

public class MainActivity extends AppCompatActivity {
    //服务端信使,为了发送数据到客户端
    private Messenger mMessenger;
    //客户端自己的信使,为了获取服务端数据
    private Messenger cMessenger;
    private static class MyHandler extends Handler {
        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case 1:
                    System.out.println("Service Data: " + msg.arg1);
                    break;
            }
        }
    }
    private ServiceConnection mServiceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            mMessenger = new Messenger(service);
            cMessenger = new Messenger(new MyHandler());
            if (mMessenger != null) {
                Message msg = Message.obtain(null, 0);
                //将客户端自己的信使放在Message里传递到服务端
                msg.replyTo = cMessenger;
                try {
                    mMessenger.send(msg);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
        }
        @Override
        public void onServiceDisconnected(ComponentName name) {
            mMessenger = null;
        }
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Intent intent = new Intent(this, MessengerService.class);
        bindService(intent, mServiceConnection, BIND_AUTO_CREATE);
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        unbindService(mServiceConnection);
    }
}

运行截图:
在这里插入图片描述

2.2 使用Bundle

Bundle
final
类型,不可被继承,它实现了Parcelable接口,是一个特殊的Map类型,支持进程间通信。
使用Bundle进行进程间通信,其实还是通过Messenger+Message来实现的,核心代码如下:

mMessenger = new Messenger(service);
Message msg = Message.obtain(null, 0);
Bundle bundle = new Bundle();
bundle.putString("IPC", "Bundle");
bundle.putInt("Number", 20);
msg.setData(bundle);
try {
    mMessenger.send(msg);
} catch (RemoteException e) {
    e.printStackTrace();
}
2.3 使用SharedPreferences

SharedPreferences
并不适合存储大量数据和频繁改变数据,只能用于轻量的存储,高并发读/写时有可能会丢失数据。
SharedPreferences
存在以下性能问题6:

跨进程不安全。由于没有使用跨进程的,就算使用
MODE_MULTI_PROCESS
SharedPreferences
在跨进程频繁读写有可能导致数据全部丢失。根据线上统计,
SharedPreferences
大约会有万分之一的损坏率。 加载缓慢
SharedPreferences
文件的加载使用了异步线程,而且加载线程并没有设置优先级,如果这个时候读取数据就需要等待文件加载线程的结束。这就导致主线程等待低优先线程锁的问题,比如一个
100KB
SP
文件读取等待时间大约需要
50 ~ 100ms
,并且建议大家提前用预加载启动过程用到的
SP
文件。 全量写入。无论是
commit()
还是
apply()
,即使我们只改动其中一个条目,都会把整个内容全部写到文件。而且即使我们多次写同一个文件,
SP
也没有将多次修改合并为一次,这也是性能差的重要原因之一。 卡顿。由于提供了异步落盘(拷贝到磁盘)的
apply
机制,在崩溃或者其它一些异常情况可能会导致数据丢失。所以当应用收到系统广播,或者被调用
onPause
等一些时机,系统会强制把所有的
SharedPreferences
对象的数据落地到磁盘。如果没有落地完成,这时候主线程会被一直阻塞。这样非常容易造成卡顿,甚至是
ANR
,从线上数据来看
SP
卡顿占比一般会超过
5%

由于以上原因,不建议使用

SharedPreferences
进行跨进程通信,特别是
SharedPreferences
进行跨进程通信不安全。

2.4 使用文件共享

利用多进程同时读写同个外部文件达到是数据交互的目的,存储形式没有限制:xml,文本,对象序列化等等。但其有着明显的缺点,由于Linux系统对文件并发读写没有限制,会导致数据不同步问题,所以该方式只适合于对数据同步要求不高的进程间通信

2.5 使用AIDL

为了使其他的应用程序也可以访问本应用程序提供的服务,Android系统采用了远程过程调用

(Remote Procedure Call,rpc
方式来实现。与很多其他的基于RPC的解决方案一样,Android使用一种接口定义语言
(Interface Definition Language,IDL)
来公开服务的接口。很多IPC通信方式都是基于
AIDL
的。如
Service
ContentProvider

AIDL
的简单使用可见:AIDL简单使用

待续 参考文章

带你了解android的IPC机制 ↩︎

Android开发之android中的多进程模式 ↩︎

Android中UID机制和共享进程 ↩︎

Android夸进程通信机制四:使用 Bundle进行进程间通信 ↩︎

Messenger:使用消息的跨进程通信 (Message.replyTo()的使用) ↩︎

Android之SharedPreferences简介及使用说明 ↩︎


作者:It一zhai男


--结束END--

本文标题: 【IPC】Android中的进程间通信(IPC)详解

本文链接: https://www.lsjlt.com/news/29533.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 浅谈并发处理PHP进程间通信之System V IPC
    目录前言Unix System V IPC信号量共享内存消息队列函数介绍ftoksemaphore函数shared_memory函数代码实现小结前言 它的安装和使用非常简单,在编译 ...
    99+
    2024-04-02
  • Android进阶手写IPC通信框架告别繁琐AIDL
    目录正文1 服务端 - register1.1 定义服务唯一标识serviceId1.2 使用方式2 客户端与服务端的通信协议2.1 创建IPCService2.2 定义通讯协议2....
    99+
    2023-01-29
    Android IPC通信框架 Android IPC
  • Python的进程间通信详解
    目录进程概述队列简介多进程队列的使用使用队列在进程间通信总结进程概述 ​ 进程(Process)是计算机中已运行程序的实体。进程与程序不同,程序本身只是指令、数据及器组织形式的描述,...
    99+
    2024-04-02
  • 操作系统进程间的摩斯电码:IPC 的艺术
    IPC 就像进程之间的摩斯电码,一种将信息从一个进程传递到另一个进程的机制。它使进程能够共享数据、同步操作并协调资源访问。在 Linux 操作系统中,IPC 具有多种形式: 管道:管道是一种单向通信机制,一个进程(写入器)向管道写入数据,...
    99+
    2024-04-02
  • 详解Android跨进程通信之AIDL
    需求描述 进程A调起第三方进程B进行第三方登录 – 实现双向通信 代码(进程A) 1.目录结构 2.LoginActivity.java public class LoginA...
    99+
    2024-04-02
  • Android中怎么实现进程间通信
    这篇文章给大家介绍Android中怎么实现进程间通信,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。由于android系统中应用程序之间不能共享内存。因此,在不同应用程序之间交互数据(跨进程通讯)就稍微麻烦一些。进程间通...
    99+
    2023-06-04
  • Android线程间通信Handler使用详解
    目录前言01、定义02、使用第一步、创建第二步、发送消息第一种是 post(Runnable)第二种是 sendMessage(Message)第三步、处理消息03、结语前言 Han...
    99+
    2022-11-13
    Android线程通信Handler Android Handler
  • Android线程间通信Handler源码详解
    目录前言01、 用法02、源码03、结语前言 在【Android】线程间通信 - Handler之使用篇主要讲了 Handler 的创建,发送消息,处理消息 三个步骤。那么接下来,我...
    99+
    2022-11-13
    Android线程间通信Handler AndroidHandler
  • Android进程间使用Intent进行通信
    安卓使用Intent来封装程序的“调用意图”,使用Intent可以让程序看起来更规范,更易于维护。 除此之外,使用Intent还有一个好处:有些时候我们只是想...
    99+
    2023-02-28
    Android Intent通信 Android进程通信
  • Node.js中的进程间通信
    目录前置知识文件描述符文件描述符的重定向shell 对文件描述符的重定向c函数对文件描述符的重定向dupdup2Node中通信原理unix domain socket是什么如何实现流...
    99+
    2024-04-02
  • Android 通过Messager与Service实现进程间双向通信案例详解
    目录Messenger使用步骤Service代码客户端代码分析结果注意事项Android中的Service和其调用者既可以在同一个App中,也可以在不同的App。如果Service在...
    99+
    2024-04-02
  • python中进程间通信详细介绍
    目录进程间通信(IPC)管道通信(Pipe)1.通信原理2. 实现方法共享内存1.通信原理2.实现方法信号量(信号灯集)1.通信原理2. 实现方法3.代码演示进程间通信(IPC) 必...
    99+
    2024-04-02
  • 进程间的通信
      使用 multiprocessing 里的 Queue() import multiprocessing def download_from_web(q): """下载数据""" # 模拟从网上下载的数据 ...
    99+
    2023-01-30
    进程 通信
  • Android进程间通信的方式有哪些
    Android进程间通信的方式有以下几种:1. Intent:通过Intent对象进行进程间的通信。可以使用隐式Intent在不同的...
    99+
    2023-10-08
    Android
  • Android进程间如何使用Intent进行通信
    这篇文章主要介绍“Android进程间如何使用Intent进行通信”,在日常操作中,相信很多人在Android进程间如何使用Intent进行通信问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Android进程...
    99+
    2023-07-05
  • Android Messenger实现进程间双向通信
    简介 Messenger是安卓进程间通信 (IPC) 最为简单的方式,可以实现进程间双向通信。详见官网介绍 代码实现 服务端应用实现 MessengerService接收客户端发送的...
    99+
    2024-04-02
  • C/C++中多进程之间的线程如何利用XSI IPC共享内存分配互斥量进行同步
    这篇文章主要介绍了C/C++中多进程之间的线程如何利用XSI IPC共享内存分配互斥量进行同步,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。#include <stdi...
    99+
    2023-06-03
  • Android 图文详解Binder进程通信底层原理
    目录🔥 什么是进程间通信🔥 什么是 Binder🔥 Android 中 IPC 的方式🔥 Binder 优势€...
    99+
    2024-04-02
  • python中进程间如何通信
    今天就跟大家聊聊有关python中进程间如何通信,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。python有哪些常用库python常用的库:1.requesuts;2.scrapy;...
    99+
    2023-06-14
  • 怎么在Android中使用AIDL实现进程间通信
    怎么在Android中使用AIDL实现进程间通信?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。一、概述AIDL 意思即 Android Interface Definiti...
    99+
    2023-05-30
    android aidl
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作