Android 中的多进程,你值得了解的一些知识

Android进阶知识树——Android 多进程、Binder 你必须知道的一切 概述 想当初在第一次拜读《Android艺术开发探索》时,深感真的是一本很“艺术”的书(因为当初菜的看不懂…),随着自己的成长和多次阅读,从开始的完全不懂到现在的有所理解、使用和总结,才体会到其中探索的奥妙,现在跟着安卓高级开发的学习路线,进一步学习、总结和梳理知识。 多进程作为Android开发者迈向高级开发者的第一关,也使许多初级开发者望而却步,这也是每个开发者必经阶段,正好笔者在公司的开发项... 阅读详情

在这里插入图片描述
引言
不知道大家在平时的开发中有没有遇到这样一个问题:自定义的 Application 类在应用启动的时候被多次创建,或者在使用到某个功能的时候 Application 再次被创建。换句话说,Application 的 onCreate() 方法被调用了两次或者更多次。

通常,我们会在 Application 里做一些应用的初始化工作。如果 Application 被多次创建的话,就会带来一些不容易发现的潜在问题。举个真实的例子,一个我曾经接手到的项目所遇到的问题:

工程中嵌入了极光推送 SDK,并且为之单独分配了一个进程(如何分配,后面会讲道)。Application 中有一些初始化的工作,其中包括一个与服务器端的网络通信请求。当时并没有注意到多进程,也就没有在 Application 中对进程做区分。这样就会出现一个问题:

有时候,应用并没有启动,而手机上其他嵌入有极光推送 SDK的应用,由于互相拉起机制,会激活我们应用中极光推送注册的服务所处的进程,Application 随即被创建,导致 onCreate() 方法中的初始化工作被执行。其中,就包括那个网络请求。而且如果一旦请求失败,比如网络出错啊,就会弹出 Toast 错误提示。那这就很奇怪了,虽然不会带来实际性的功能问题,但是使用在玩手机时莫名弹出一个错误提示,这种体验就不好啦。

像这种问题,还不太好测试,进程间的互相拉起,再加上网络通信错误而发生 UI 上的变化,条件苛刻,很难复现。但其实只要我们在开发中稍微注意一下多进程的问题,就可以很容易地避免这种问题。下面就来聊聊多进程的来龙去脉。

关于进程

大家知道,一个应用中通常包含多个线程,用于处理耗时任务,防止 ANR 之类的错误。但是一个应用其实也能包含多个进程,只是一般用不到而已。

由于 Android 系统特有的机制,会为每个 App 单独分配一个进程,同时赋予一定大小的内存供其使用。这样,进程之间,或者说 App 之间都是独立运行的,彼此不会互相影响。比如,不会发生某一个 App 崩溃出错导致其他 App 也跟着无法使用的状况。

那么这么多进程争夺系统内存等资源,而系统资源是有限的,怎么办呢?别急,有进程优先级。当系统内存资源不足时,为了保证高优先级的进程能够顺畅使用,那些低优先级的进程很容易被系统杀掉,从而释放资源。更多进程优先级的知识,可以阅读文章末尾的参考链接。

为什么要使用多进程

通常,我们应用中的 Activity、Service 等四大组件默认都位于一个进程里面,并且这个进程名称的默认值就是我们给应用定义的包名。既然有了一个默认的进程,为什么还要使用多进程呢?

前面我们说道,系统为每个进程分配的内存是有限的,比如在以前的低端手机上常见是 16M,现在的机器内存更大一些,32M、48M,甚至更高。但是,总是有限的,毕竟一个手机出厂之后 RAM 的大小就定了,总是无法满足所有应用的需求。

当然,你可以在 Application 中通过使用 largeHeap 属性为自己应用所处的进程争取分配更大的内存,就像这样:

......

但也存在不够用的可能,一旦超出,马上发生 OOM,内存溢出。

所以,一个明智的选择就是使用多进程,将一些看不见的服务、比较独立而又相当占用内存的功能运行在另外一个进程当中,主动分担主进程的内存消耗。常见如,应用中的推送服务,音乐类 App 的后台播放器等等,单独运行在一个进程中。

使用多进程还有一个好处就是,互相拉起。当然,这显得有些流氓,然而你会发现市场上很多全家桶之类的应用确实是这么做的。某种程度上,这种做法也能够保证自家应用的功能更好地服务用户。

如何使用多进程

在项目中使用多进程操作起来非常简单,在 AndroidManafest.xml 清单文件中注册 Activity、Service 等四大组件时,使用 android:process 属性指定进程名即可,如:

该属性值的命名也是有一定规则的:

如果像上面这样,以冒号 “:” 开头,那么该组件所处的进程就是一个私有进程。当这个组件被启动运行时,该进程随即被创建,并且进程名为应用包名加上这里定义的 ProcessName 名称;

如果是以小写字母开头,该进程就是一个全局进程,可以和其他应用共享,减少资源占用。这里的进程名就是属性值定义的这个字符串。

注意:作为 android:process 属性值的字符串,在名称的定义上,必须符合 Android 包名的命名规范。你不能以数字开头,或者大写字母开头等。否则,编译时会报错。

如果你在调试一个多进程的应用,并且多个进程处于运行状态,在 Android Studio 的 Android Monitor 调试界面,可以直接看到多个进程名同时存在:

使用多进程的注意事项

使用多进程,特别要注意的一点就是:Application 的重复创建。如果你注册四大组件中的任意一个组件时用到了多进程,运行该组件时,都会创建一个新的 Application 对象。关于这一点,在老罗的博客中有所介绍,可以访问文章末尾的参考链接了解相关知识。

多数情况下,我们都会在工程中自定义一个 Application 类,并且将一些全局性的初始化工作放在这个类里面。当这个类多次创建时,如果不对进程加以区分的话,我们的这些初始化工作也会被执行多次。除了影响应用的启动时间,还有可能就会出现其他问题。比如,文章引言部分,我曾经遇到的案例。

对于多进程重复创建 Application 这种情况,只需要在该类中对当前进程加以判断即可。比如,一些主进程内的应用初始化工作只在主进程的 Application 中执行。前面我们提到,主进程默认使用的是应用包名作为进程名,而其他的进程名也是我们自由定义的。所以,判断当前进程是谁,自然也不是难事:

在 Application 中获取当前进程 ID,再根据进程 ID 获取进程名,有选择地做一些初始化工作:

@Override
public void onCreate() {
super.onCreate();

String processName = AppUtility.getProcessName(Process.myPid());
if (getPackageName().equals(processName)) {
    // init
}

}
和

/**

  • 根据进程 ID 获取进程名
  • @param pid
  • @return
    */
    public static String getProcessName(int pid){
    ActivityManager am = (ActivityManager) MainApplication.getContext().getSystemService(Context.ACTIVITY_SERVICE);
    List processInfoList = am.getRunningAppProcesses();
    if (processInfoList == null) {
    return null;
    }
    for (RunningAppProcessInfo processInfo : processInfoList) {
    if (processInfo.pid == pid) {
    return processInfo.processName;
    }
    }
    return null;
    }

除了利用 ActivityManager 服务获取当前进程名,还有一种黑科技,不妨看看:

public static String getProcessName() {
try {
File file = new File("/proc/" + android.os.Process.myPid() + “/” + “cmdline”);
BufferedReader mBufferedReader = new BufferedReader(new FileReader(file));
String processName = mBufferedReader.readLine().trim();
mBufferedReader.close();
return processName;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}

这是多进程对 Application 的影响,以及我们使用中的注意事项。前面我们说到,多个进程之间彼此独立,你所定义的那些全局静态数据等,在进程之间是不能直接共享使用的。比如,如果你在 Application 中定义了一个全局的 Activity 数组来管理应用中的 Activity,同时你又用到其他进程运行某些 Activity,那你在应用完全退出这种使用场景下就得多加注意了。

如果你一定要在多进程中通信,有可能就要用到 AIDL 机制,或者利用文件这种数据持久化操作实现。关于 AIDL 的知识,本文就不再深入探讨啦,大家可以自行查找相关资料。

最后小编给大家准备了安卓进阶学习资料
加群:4112676
在这里插入图片描述
在这里插入图片描述

Android 应用内多进程实现 单APK应用多进程 Android平台支持多进程通信,也支持应用内实现多进程,Android中,默认一个APK包就对应一个进程,其进程名就为AndroidManifest.xml文件中 指定的package名。我们可以通过Activity,Service,BroadCastReceiver,ContentProvider的android:process属性来实现单APK多进程,但是需要注意进程间内存的不可见性。 阅读详情

相关推荐

Android多进程运行机制及IPC

某些应用自身需要采用多进程模式,如在 Android 中对一个应用获取的最大内存做了限制,为了使自己的应用获取更多内存空间而将一些模块放在独立进程中,此时模块之间的交互就需要进程间通信来完成;应用本身需要跨进程与其他应用交互,无论是使用 ContentProvider 还是 AIDL 都属于 IPC 的范畴,如在 Android 机顶盒 IPTV 中间件中就有大量使用。:Android 对应用内存的限制不同厂商不同,默认分配的初始内存是 16M,具体配置在 system/build.prop 文件中。

keyoukewude的博客 1017

Android多进程理解一

一、Java进程和线程 进程是操作系统进行资源分配和调度的一个独立单位。  独立性(每个进程都有自己独立私有的一块内存空间)、动态性、并发性(多个进程可在单处理器上并发执行) 并发是指在同一时间点只能有一条指令执行,但多个进程指令被快速轮换执行,使得在宏观上具有多个进程同时执行的效果。 并行指在同一时间点,有多条指令在多个处理器上同时执行 线程 包含在进程中。一个进程可以包含多个线程...

sduliulun的专栏 336

Android多进程Process开发总结-优点与缺陷

Androiod多进程为何使用多进程 什么情况下,我们会去想到使用多进程呢? 就我个人开发实践中就多次使用了Android多进程机制,如项目中的推送业务开发,提出要求如下: - 不能影响主业务的代码稳定运行 - 不能占用主业务的进程内存 - 不受主业务进程生命周期影响,独立存在和运行 要满足这3个需求下,不由就会想到在应用内开辟一个新进程单独给推送业务使用,因为其特点明显:

在路上-codingAndlearning 9878

【Android】获取当前进程名的四种方法及效率对比

...

qq_23049111的博客 4877

Android中的多进程

在Android中也可以像pc一样开启多进程,这在android的编程中通常是比较少见的,以为在一个app基本上都是单进程工作就已经足够了,有一些特殊的场景,我们需要用多进程来做一些额外的工作,比如下载工作等。在Android的中,每一个activity或者service都可以指定一个进程名称,当这个activity或者service被调用时,该进程自动启动。因此在android中启动一个进程是比较简单的,如果需要看一个app有几个进程,看的就能知道有几个进程。

haleycat的博客 1014

Simulink实战:火电机组一次调频与AGC协同控制建模与仿真解析

本文详细解析了如何使用Simulink进行火电机组一次调频与AGC协调控制的建模与仿真。通过系统架构设计、参数设置和模块实现,阐述了如何实现两者的协同控制,确保电网频率稳定。文章提供了实用的建模技巧、参数整定经验和性能评估方法,为电力系统仿真工程师提供了有价值的实践指导。

c7d8e9的博客 307

如何理解Android的多进程

平时的工作中,有时会遇到多进程编程,也会涉及到多进程之间的通信,那么Android的多进程到底是怎么回事,该如何理解Android的多进程呢? 在读本篇文章之前还需要明确一点,这儿说的多进程是指一个应用中存在多个进程的情况。而在理解Android多进程之前,先来介绍一些简单的概念。 区分线程与进程的概念 根据所查资料,先分别介绍下它们的概念: 进程:是一个具有独立功能的程序关于

cmyperson的博客 874

从硬件异常到代码救赎:RH850内存访问错误(MAE)的深层诊断与艺术

本文深入探讨瑞萨RH850微控制器的内存访问错误(MAE)诊断与解决方法。针对程序跑飞和Flash Driver交互中的潜在陷阱,提供系统性硬件异常分析框架和防御性编程实践,帮助嵌入式开发者从底层机制到代码层面有效预防和修复MAE问题,提升系统稳定性。

pytorch8learner的博客 195

Android中的多进程开发以及多进程的使用场景

在Android中,默认情况下,同一应用的所有组件均运行在同一进程中,且大多数应用都不会改变这一点。不过,单进程开发并不是Android应用的全部,今天我们就来说说Android中的多进程开发以及多进程的使用场景。 多进程介绍 本篇文章内容基于Android Developer 在Android中,默认情况下,同一应用的所有组件均运行在同一进程中,且大多数应用都不会改变这一点。不过,单进程开发并不

lizhaopeng 1402

告别反复刷写:用英飞凌XCP Overlay功能实现ECU标定与诊断的‘热更新’

本文详细介绍了英飞凌XCP Overlay功能在ECU标定与诊断中的应用,实现参数的'热更新',避免反复刷写Flash。通过地址重映射技术,将标定变量从Flash重定向到RAM,显著提升工作效率并保护Flash寿命。文章涵盖技术原理、工程实践、功能安全考量及高级应用场景,为汽车电子工程师提供完整解决方案。

weixin_30689307的博客 524

2023东华大学OJ机试题22-70

东华大学计算机考研复试机试22 约瑟夫环223、整除的尾数24、回文质数25、汽水瓶26、阶乘最后的非0位27、算菜价28、 水果价格29、求奇数的乘积30、求最晚和最早日期31、素数32、计算e33 数字之和34 繁殖问题35 奇妙的数字36 整除的尾数37 黑色星期五38 树39 约瑟夫环40 最大与最小41 环42 求数列项43 最高频率44 三艘船45 回文数46 特殊四位数47 最大值48 数列149 修理牛棚50 按要求输出序列51 部落人乘法52 序列53 双重回文数54 等差数列55 人见人

m0_49263811的博客 2598

(十二)安卓进程与多进程

在安卓应用开发中,进程和多进程技术用于实现复杂的应用架构、提升应用性能和增强安全性。理解如何有效地使用多进程,可以帮助开发者分离不同模块的功能、实现高效的进程间通信以及提升应用的稳定性和安全性。本文将介绍进程和多进程的基础知识、在安卓平台上的实现方法、常见的使用场景以及一些实践示例,帮助你全面掌握安卓进程与多进程技术。进程是操作系统进行资源分配和调度的基本单位,是程序在一个数据集合上运行的过程。每个进程拥有独立的内存空间和系统资源。掌握进程和多进程技术是开发复杂安卓应用的关键。

小新的博客 890

【算法设计与分析】期末复习题(超详细)

刚刚整理了一下电脑的文件,发现了这份上学期的算法设计与分析期末复习题,有需要的文后自取。

a1234567822的博客 6611

Android中的多进程通信方式

Android中的多进程通信方式多种多样,每种方式都有其特定的使用场景和优缺点。开发者需要根据具体的需求和场景选择合适的IPC机制来实现跨进程通信。同时,还需要注意数据一致性、安全性、性能考虑、并发控制、稳定性和兼容性等方面的问题以确保通信的可靠性、安全性和效率。通过合理地使用多进程通信机制,可以实现不同进程间的数据共享和功能调用从而提高应用的稳定性和性能。

Good_tea_h的博客 1832

嵌入式工程师必看:BLDC电机驱动电路设计全流程(附MOS管选型指南)

本文为嵌入式工程师提供了BLDC电机驱动电路设计的全流程实战指南。文章深入解析了三相全桥逆变电路的核心原理,并重点阐述了功率MOSFET的选型关键参数,如Vds、Rds(on)和Qg。同时,详细介绍了栅极驱动设计、PCB布局布线要点及调试安全步骤,旨在帮助开发者构建稳定高效的BLDC驱动系统。

weixin_29194817的博客 587

Linux DRM驱动实战:手把手教你用drmModeSetCrtc显示纯色画面(附完整代码)

本文提供了一份完整的Linux DRM驱动实战指南,手把手教你使用drmModeSetCrtc在屏幕上显示纯色画面。文章详细解析了从打开设备、获取资源、创建帧缓冲区到最终提交画面的完整调用流程,并附带了可直接编译运行的完整代码示例,帮助开发者快速上手Linux图形底层开发。

weixin_29216353的博客 511

[Android]多进程知识点详解

如果想要成为架构师或想突破20~30K薪资范畴,那就不要局限在编码,业务,要会选型、扩展,提升编程思维。此外,良好的职业规划也很重要,学习的习惯很重要,但是最重要的还是要能持之以恒,任何不能坚持落实的计划都是空谈。如果你没有方向,这里给大家分享一套由阿里高级架构师编写的《Android八大模块进阶笔记》,帮大家将杂乱、零散、碎片化的知识进行体系化的整理,让大家系统而高效地掌握Android开发的各个知识点。.........

大模型学习路线 3367

飞牛NAS打造成童年经典游戏机

这篇文章介绍如何使用飞牛NAS搭建经典游戏模拟器。首先需开启Docker并下载RetroArch-web镜像,随后创建容器并设置端口映射。启动后上传游戏ROM文件(如NES格式),在模拟器中加载即可游玩。文章以修改版坦克大战为例,详细说明按键配置方法。同时还提到公网访问需配置DDNS或使用ZeroTier内网穿透。通过这套方案,用户可以在NAS上重温红白机等经典游戏体验。

dgnankai的专栏 884

android开发 多进程的基本了解

android为每个进程都分配一个独立的虚拟机,不同的虚拟机在内存上有不同的地址空间,导致在不同的虚拟机中访问同一个类的对象会产生多份副本。结合本例,com.jn.testbrodercast与:remote进程都存在一个Book类,互不干扰,在一个进程中修改id只会影响当前进程。进程名以“:”开头的进程属于当前应用的私有进程,其他应用的组件不可以和它跑在同一个进程中,而进程名不以“:”开头的进程属于全局进程,其他应用通过ShareUID方式可以和它跑在同一进程中。增加一个类BOOK,并添加静态变量id。

来来来,走一走 712

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

Android——多进程

之前我们了解了 : -----------------------------------Java——多线程浅析. -----------------------------------Android——Handler详解 -----------------------------------Android——HandlerThread浅析 -----------------------------------Java——ThreadPool线程池 让我们继续看看Android多进程: 1. 概述 默认情况

Yawn 3485

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

Android中的多进程模式

开启多进程模式

YoungTr的专栏 4547

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

Android IPC | Android多进程模式

Android系统会为每个应用分配一定的内存,但是有些功能十分消耗内存,比如查看图片这种功能,这时为了防止该功能导致应用内存过多导致OOM,可以把该功能单独拎出来,在单独进程中进行,这样就可以获取双份内存,突破了单一应用的内存限制。关于Android的进程间通信(即IPC)有很多种方式,比如我们常用的AIDL、Socket等,而其中最重要而且最需要掌握的就是AIDL的使用和原理,简单来说它是通过Binder实现的。

编程进化论 1164

Android多进程

经过模块解耦,开辟新的进程,独立的JVM,来达到数据解耦目的。解析:绑定服务端的Service,绑定成功后,将服务端返回的Binder对象转成AIDL接口所属的类型,然后就可以调用AIDL中的方法了,客户端调用远程服务的方法,被调用的方法运行在服务端的Binder线程池中,同时客户端的线程会被挂起,如果服务端方法执行比较耗时,就会导致客户端线程长时间阻塞,导致ANR,客户端的onServiceConnected和onServiceDisconnected方法都在UI线程中。

Dream It Possible 1095

Android中的多进程通信

Android中的多进程

洞悉玄机的博客 1339

开启多进程android,Android中的多进程模式

2.2 Android中的多进程模式在正式介绍进程间通信之前,我们必须先要理解Android中的多进程模式。通过给四大组件指定android:process属性,我们可以轻易地开启多进程模式,这看起来很简单,但是实际使用过程中却暗藏杀机,多进程远远没有我们想的那么简单,有时候我们通过多进程得到的好处甚至都不足以弥补使用多进程所带来的代码层面的负面影响。下面会详细分析这些问题。2.2.2 开启多进程...

weixin_34582773的博客 544
上一篇: Android开发如何进阶?
下一篇: 详解Android刘海屏适配
AndroidUpUp
博客等级 码龄8年 1粉丝 11原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值