Android:多进程的开启方式、注意点以及如何解决。

2023-10-27

前言

线程是CPU调度的最小单元。而进程一般指一个执行单元,在PC和移动设备上指一个程序或者一个应用。一个进程可以包含多个线程,进程和线程是包含与被包含的关系。
在很多中情况下我们需要开启多进程,最常见的比如某一个模块会占用很多的内存且比较独立,可以考虑放到单独的进程去处理。
但是多进程不仅仅是简单指定一个进程名称就好了,下面会进行详细介绍。

多进程的开启方式

Android中开启多进程常规的话只有一种方式,给四大组件(ActivityServiceReceiverContentProvider)在AndroidMenifest中指定android:process属性。除此之外还有另一种非常规的方法,就是通过JNInative层去fork一个新的进程。

常规来说都是在AndroidMenifest中指定android:process来开启多进程,可以看下面的示例。

<activity
    android:name=".view.ClientActivity1"
    android:process=":client1" />

<activity
    android:name=".view.ClientActivity2"
    android:process="com.howie.client.client2" />

当前的应用包名为com.howie.multiple_process

所以当应用启动之后:

  • 应用的默认进程即为com.howie.multiple_process
  • 当启动ClientActivity1之后,会启动一个名为com.howie.multiple_process:client1的进程;
  • 当启动ClientActivity2之后,会启动一个名为com.howie.client.client2的进程;

可以运行程序看一下效果,利用AndroidStudioLogcat查看当前应用的进程数。

在这里插入图片描述

也可以利用adb shellps命令搜索匹配进程,比如我们输入adb shell "ps | grep com.howie",会打印出如下信息。

u0_a428       9555  1042 14592908 101172 0                  0 S com.howie.multiple_process
u0_a428       9690  1042 14608640 95004 0                   0 S com.howie.multiple_process:client1
u0_a428       9728  1042 14608640 95724 0                   0 S com.howie.client.client2

需要注意的是,ClientActivity1ClientActivity2android:process属性值分别为:client1com.howie.client.client2

这两种命名如下两个区别:

  1. 进程名字不同,:的进程名字为当前的进程名前附加上包名。如上所示,ClientActivity1的包名即为com.howie.multiple_process:client1;
  2. 进程名以:开头的话代表当前进程是应用程序的私有进程,其他应用的组件不可以和它跑在同一个进程;而不以:启动的进程属于全局进程,其他应用进程可以通过共享UID方式可以和它泡在同一个进程当中。两个应用通过ShareUID跑在同一个进程下需要相同的签名,此时可以互相访问对方的私有数据、还可以共享内存数据,看起来就像同一个应用的两个部分。

多进程注意点

通过指定android:process就可以开启多进程了,但是多进程还是有许多注意的地方的。不仅仅只是指定一个android:process就代表万事大吉了。

首先我们需要知道,Android应用的一个简单的启动过程。

  1. 桌面(Launcher进程)→AMS(SystemServer进程)→Zygote进程→由Zygote fork自身创建应用程序进程
  2. 创建应用程序进程,应用程序进程是通过请求Zygote进程来创建新的应用程序进程。Zygote进程通过fock自身创建应用程序进程,这样应用程序进程就会获得Zygote进程在启动时创建的Java虚拟机实例,同时在应该程序进程创建过程中还启动了Binder线程池以及消息循环。
  3. 应用程序进程创建出来之后,由AMS去请求应用程序进程去创建启动Activity

在这里插入图片描述

回到我们的本片文章的主题,多进程的注意点,我们需要注意的是,在创建进程的时候同时创建了Java虚拟机不同的虚拟机在内存分配上有不同的地址空间,导致在不同的虚拟机中访问同一个类的对象会产生多份副本

比如我可以写如下的代码,在两个进程中同时访问使用。

object DataManager{
	var id = 1
}

我们在MainActivity中将其改变设置为2,之后再ClientActivity1中打印出该值。

我们期望再ClientActivity1中打印的值为2,但其实打印出来的是1

这就是因为在这两个进程管理的内存地址不同,由两个虚拟机进行处理。简单理解就是DataManager再这两个进程中都存在,且这两个类互不干扰,同理这两个进程都存在自己的DataManager单例实例。所以修改当前进程的对象属性并不会影响到另一个进程。

多进程直接通过内存来共享数据,无一例外都会失败,这也是开启多进程带来的主要影响。

总的来说来说多进程主要会遇到以下几个问题。

  1. 静态成员和单例模式失效
  2. 线程同步机制失效
  3. SharedPreferences会存在丢数据的可能
  4. Application在每次创建一个新的进程时都会重新走一次

第一点上面有讲过;第二点和第一点类似,线程同步只保证当前进程多线程同步,另一个进程的无法保证;第三点因为在内存中会有一份SharedPreferences文件的缓存,在多进程模式下,它的读/写就变得不可靠,当面对高并发的读/写访问,Sharedpreferences有很大几率会丢失数据;第四点在进程启动之后启动Activity的过程中会首先启动Application,所以启动多少个进程就会启动多少个虚拟机然后执行多少次Application。所以如果你存在多进程但是部分在Application中的逻辑只想执行此一次,可以判断进程名字,然后再想要的进程中执行。

android:multiprocess是干什么的?

AndroidManifest.xml清单中还有一个属性即为multiprocess
从上面我们知道指定了process名字之后就可以开启多进程了,那么multiprocess又是干嘛呢?
我们思考一个这样的问题,主进程是process1,又启动了一个进程process2,现在存在一个新的Activity,我们希望它运行在调用者的进程中,那么如何操作呢?
这时候只需要将android:multiprocess = true则该Activity就会运行到调用者的进程中了。如果是process1调用启动该Activity,那么它就会运行在process1中;如果是process2调用启动该Activity,那么它就会运行在process2中。
默认情况下android:multiprocess = false,此时不论那个进程调用打开该Activity,如果该Activity指定了process属性,那么它运行在指定的进程中,否则运行到主进程中。

几种跨进程通信的方法

实现跨进程通信的方式很多。

  1. 通过Intent来传递数据。
  2. 共享文件。
  3. 基于BinderMessenger
  4. 基于BinderAIDL
  5. Socket

平时常用的的通过Intent传递数据的方式其实就是一种跨进程的方案,需要序列化。另外还可以使用共享文件Socket等等。当然Android中比较常用的还是Binder了,后面会就Binder进行详细的解析。
关于文件共享可以参考之前写的一篇测试文章:Android多个进程同时写同一个文件,会怎么样?
IPC : 多进程 Binder-AIDL 使用指南、包含案例

创作不易,如有帮助一键三连咯

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android:多进程的开启方式、注意点以及如何解决。 的相关文章

随机推荐

  • w7系统如何关闭高级文字服务器,Win7系统怎么取消切换大小写时出现提示?

    Win7系统用户在工作中使用键盘切换大小写输入时 总会弹跳出系统的提示窗口 很多用户觉得非常烦 那么Win7系统应该怎么取消切换大小写时出现的提示呢 接下来下面请看Win7系统切换大小写时出现的提示的具体解决方法 解决方法 1 首先 在桌面
  • 在Vue中获取DOM元素的实际宽高

    最近使用 D3 js 开发可视化图表 因为移动端做了 rem 适配 所以需要动态计算获取图表容器的宽高 其中涉及到一些原生DOM API的使用 避免遗忘这里总结一下 一 获取元素 在 Vue 中可以使用 ref 来获取一个真实的 DOM 元
  • 电商峰值系统架构设计--转载

    1 1 系统架构设计目录 摘要 双11来临之际 程序员 以 电商峰值系统架构设计 为主题 力邀京东 当当 小米 1号店 海尔商城 唯品会 蘑菇街 麦包包等电商企业 及商派 基调网络等服务公司 分享电商峰值系统架构设计的最佳技术实践 自200
  • SSH_Unable to negotiate with ... port ..: nomatching host host key type found. Their offer:ssh-rsa

    终端远程登录ssh时 提示如下错误 Unable to negotiate with 192 168 1 228 port 22 nomatching host host key type found Their offer ssh rsa
  • 常见的损失函数(loss function)总结

    点击上方 小白学视觉 选择加 星标 或 置顶 重磅干货 第一时间送达 导读 本文总结了常见的八种损失函数的优缺点 包括 0 1损失函数 绝对值损失函数 log对数损失函数 平方损失函数 指数损失函数 Hinge 损失函数 感知损失函数 交叉
  • 解答:pytorch 通过索引赋值后 梯度还能正常反向传播吗

    先上测试代码 if name main scene graph token tensor1 torch rand 4 4 tensor1 requires grad True tensor2 torch rand 4 tensor2 req
  • labelme标注不同物体显示不同颜色以及批量转换

    最近在使用labelme标注数据时遇到一些问题 如上图中 蓝色分别为crack person dog三类 正常应该是3种不同颜色 解决方案 1 labelme版本 2 下载labelme后进行文件修改 由于博主想要的是rgb三通道的彩色图
  • pytorch量化库使用(1)

    量化简介 量化是指以低于浮点精度的位宽执行计算和存储张量的技术 量化模型以降低的精度而不是全精度 浮点 值对张量执行部分或全部运算 这允许更紧凑的模型表示以及在许多硬件平台上使用高性能矢量化操作 与典型的 FP32 模型相比 PyTorch
  • 容器技术之Chroot&Docker

    chroot 容器技术从1979年chroot的首次问世便已崭露头角 维基百科对chroot的定义如下 是在 Unix 和 Linux 系统的一个操作 针对正在运行的软件进程和它的子进程 改变它外显的根目录 一个运行在这个环境下 经由 ch
  • 清华梦的破碎--写给清华大学的退学申请

    注记 每个不是根据自己的爱好而是根据行业前景而选择互联网产业的学子都会遇到很多的困惑和迷茫 作为天才式的博士生王垠也曾遇到过很多类似的困境 读完这篇文章 感觉遇到不少的相同情况 或许这篇文章能够指引你不少的道路 故向你推荐这篇文章 清华梦的
  • 基于unapp的自定义picker组件

    基于unapp的自定义picker组件
  • 区块链在版权保护上有什么作用?

    我国在版权保护方面的制度和法律越来越完善 版权行业的规模也是不断扩大 虽然版权行业的确权的发展有一定的时间 但其还存在着一些问题 那目前比较前沿的区块链版权保护应用又能有效解决这些问题呢 根据腾讯研究员的数据 中国网络核心版权产业行业规模从
  • 【Java预科】CH02 常用快捷键和基本DOS命令

    上一课 MarkDown语法 常用快捷键 Tab键切换菜单键或空四个格子 shift键是功能键 ctrl键是控制键 alt键 具体使用 Ctrl C复制 Ctrl V粘贴 Ctrl A全选 Ctrl X剪切 Ctrl Z撤销 Ctrl A保
  • 无框架的底层代码实现普通RNN、LSTM的正反向传播过程及应用

    1 准备 首先导入所需要的包rnn utils py import numpy as np def softmax x e x np exp x np max x return e x e x sum axis 0 def sigmoid
  • 4小时入门深度学习+实操MMDetection 第二课

    视频 4小时入门深度学习 实操MMDetection 第二课 目标检测工具包 一完成目标检测 二完成实例分割 很方便可以进行模块替换 pytorch 4万多star 几行pathon API即可调用强大的检测能力 配置文件修改 可以训练自己
  • Linux命令行——touch命令详解

    1 命令功能 touch命令用于创建文件或修改文件 目录的时间戳 了解时间戳 可以查看Linux命令行 stat命令详解 2 语法格式 touch option file 3 参数选项 无选项 若文件不存在 则创建新的空文件 access
  • 【shell实战案例】批量注释nginx的重定向并进行文件对比

    业务背景 线上配置中nginx存在大量 return 301重定向的配置 根据必须注释 文件夹下有大量文件 每个文件都有很多行 由于登录服务器有点麻烦 希望通过shell脚本处理 如何注释 ls xargs I sed i 301 s 解释
  • 基于ESP8266的遥控小车

    如何操控小车 这个问题问的好 相信许多学习过单片机的小伙伴们都知道我们控制一个硬件的方法有很多种 例如红外遥控 蓝牙遥控等等 但是我们今天介绍的是用wifi和服务器进行遥控 那么wifi怎么控制我们的小车呢 其实原理与蓝牙相似 只不过esp
  • 开始第一张“码绘”——使用P5.JS画出旋转的爱心

    用P5 JS画出旋转的爱心 首先我们来看看想实现的原图 对这张图片进行观察可以发现图中一共有16颗相同的爱心在旋转 我们拿出其中一个爱心进行分析 我们可以发现 这个爱心是由27个正方体构成 此处应该注意的是 是正方体 而不是正方形 应该用b
  • Android:多进程的开启方式、注意点以及如何解决。

    前言 线程是CPU调度的最小单元 而进程一般指一个执行单元 在PC和移动设备上指一个程序或者一个应用 一个进程可以包含多个线程 进程和线程是包含与被包含的关系 在很多中情况下我们需要开启多进程 最常见的比如某一个模块会占用很多的内存且比较独