65%更小的APK和70%更少的内存:如何优化我的Android App的内存

2023-10-23 13:46

本文主要是介绍65%更小的APK和70%更少的内存:如何优化我的Android App的内存,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

65%更小的APK和70%更少的内存:如何优化我的Android App的内存

(Note: This is a translation of the provided title)

为什么应用程序内存很重要?

使用最少的内存的高效应用程序可以提升性能,节省设备资源并延长电池寿命。它们提供流畅的用户体验,并且在应用商店中更受欢迎。这样的应用程序与各种设备兼容。

跟踪内存的方法

我们可以采用以下任一方法来跟踪应用程序的内存:

1. ADB 命令

要在特定时刻获取应用程序的内存,请在终端中运行以下命令:

adb shell dumpsys meminfo appPackageName

注意:将 ‘appPackageName’ 替换为您要监视的应用程序的实际包名。

上面的示例截图显示该应用程序的内存使用量为 42MB。

优点
获取设备中任何应用程序的内存。
限制
无法像 Android Profiler 那样根据用户交互以图表形式监视内存变化。

2. Android Profiler

启动 Profiler 的步骤

View(在顶部窗格)-> Tool Windows -> Profiler -> 点击 “+” -> 选择设备和包

优点
Android Profiler 可以根据应用程序的使用情况跟踪运行时行为和内存消耗。
它提供了对应用程序内存的全面视图。
限制
只能对“可调试的应用程序”进行性能分析。

注意:请注意,本文档中不涉及内存分析。要获取更深入的信息,请参阅官方文档。

我们的应用程序在图像方面非常重要,并且我们已经注意到,在浏览了 47 张图片后,应用程序的内存使用量超过了 500MB(如上面的截图所示)。这将增加遇到内存溢出异常 (OOM) 的风险。我们意识到需要进行内存优化以提高用户体验,并采取了以下措施。让我们开始吧…

内存优化措施

1. 像素颜色格式更改

像素颜色格式:像素颜色格式,也称为像素格式,指定了图像中每个像素的颜色信息在内存中的存储方式。它定义了红色、绿色、蓝色和 alpha(透明度)组件的排列方式,影响着颜色质量和渲染性能。

在 Android 中,支持多种颜色格式。然而,让我们重点关注下面最常用的几种。

ARGB_8888(每像素32位)- 8 位用于 alpha(透明度),8 位用于红色,8 位用于绿色,8 位用于蓝色

RGB_565(每像素16位)- 5 位用于红色,6 位用于绿色,5 位用于蓝色,没有 alpha

如上图所示,RGB 565 和 ARGB 8888 之间的差异几乎不可察觉,但是在 RGB 565 中内存减少了约 50%。

我们使用 Glide 库进行图像渲染。默认情况下,Glide 使用 ARGB 8888 像素颜色格式进行图像加载。然而,Glide 提供了配置首选像素颜色格式的灵活性。

@GlideModule
class CustomGlideModule : AppGlideModule() {override fun applyOptions(context: Context, builder: GlideBuilder) {builder.setDefaultRequestOptions(RequestOptions().format(DecodeFormat.PREFER_RGB_565))}
}

如上所示,我们在应用程序级别上将默认颜色格式调整为RGB 565。此配置更改导致每个像素的内存消耗减少50%。对于依赖图像的项目,这个决策非常重要。

注意:RGB 565具有某些限制,例如轻微的颜色变化和不支持透明度。这可能会导致特定图像的颜色精度降低,因此选择应基于应用程序的特定要求而做出。

2. Glide DiskCacheStrategy 更改

DiskCacheStrategy主要确定图像在设备上的缓存方式。

先前,我们使用的是“DiskCacheStrategy.All”。但是,在进行一些研究后,我们意识到“DiskCacheStrategy.Resource”更符合我们的特定需求。

DiskCacheStrategy.ALL -> 缓存图像的所有版本。

DiskCacheStrategy.Resource-> Glide仅在磁盘上缓存所有转换(例如调整大小,裁剪)后的最终图像。当您想要缓存完全处理的图像而不是原始数据时,此策略是理想的。

官方文档中可以引用其他DiskCacheStrategies

例如,在WhatsApp等应用程序中,图像通常以压缩格式显示。但是,偶尔用户可能想要在其原始的高分辨率状态下共享这些图像。在这种情况下,DiskCacheStrategy.Resource将不适用。

因此,diskCacheStrategy的选择取决于应用程序的特定要求。

** 3. 修改offscreenPageLimit **

最初为了最小化延迟和防止空白屏幕,我们将offscreenPageLimit配置为3以用于ViewPager。我们的假设是ViewPager会缓存前一页,当前页和下一页。然而,经过更深入的调查,我们发现它实际上缓存了前三页,当前页和下三页,这导致总共存储了7个大型高清晰度图像。

基于这个分析,我们选择将offscreenPageLimit减少到1。这不仅减少了内存使用,还使应用程序在没有任何延迟问题的情况下平稳运行。

viewPager.offscreenPageLimit = 1

4. onViewRecycled时清除缓存

onViewRecycledRecyclerView.Adapter中的回调方法,在视图被回收时触发。它通常与Glide一起使用,以取消正在加载的图像,优化内存和网络使用。

override fun onViewRecycled(holder: ChildBingeHolder) {GlideApp.with(context).clear(yourView)
}

在适配器中回收视图时清除视图缓存有助于释放内存。

5. 指定图像大小

我们有一个64x64像素(小型)ImageView,但API提供的是512x512像素(大型)图像。为小占位符解码如此大的图像在内存使用和应用程序性能方面效率低下。

为了解决这个问题,我们指定了视图的宽度和高度,以确保正确缩放图像,而不是将超大的图像加载到内存中。

Glide.with(this).load(IMAGE_URL).override(targetWidth, targetHeight).into(imageView)

使用override()可以通过指定所需的图像尺寸来大大减少内存消耗,这在处理大型图像或同时显示多个图像时特别有用。

6. 处理onTrimMemory

实现onTrimMemory(int)以根据系统约束逐步释放内存。这通过使您的进程更长时间地保持活动状态来改善系统响应性和用户体验。如果没有资源修剪,系统可能会杀死您的缓存进程,需要您的应用程序重新启动并在用户返回时恢复状态。

注意:以下内存级别处理是针对我们应用程序的特定要求进行定制的。我们正在根据需要自定义内存级别。内存级别文档

override fun onTrimMemory(level: Int) {//Memory Levels documentation : https://developer.android.com/reference/android/content/ComponentCallbacks2// TRIM_MEMORY_COMPLETE & TRIM_MEMORY_MODERATE are the levels which are called when the app is in backgroundif (level == android.content.ComponentCallbacks2.TRIM_MEMORY_COMPLETE) {GlideApp.get(this).clearMemory()} else if (level == android.content.ComponentCallbacks2.TRIM_MEMORY_MODERATE) {GlideApp.with(this).onTrimMemory(TRIM_MEMORY_MODERATE)}
}

在实施上述步骤并进行一些微小的调整后,我们成功地实现了应用程序内存管理的显著改进。

在提供的屏幕截图中,我们可以观察到内存行为。它清楚地表明,内存保持不变,并且在不断滚动图像期间有效地管理任何未使用的内存。

结果:

如上表所示,内存使用从浏览47张图像时的515MB减少到浏览67张图像时的137MB(超过70%的减少)。这种改进使我们能够在不担心内存限制的情况下向应用程序添加更多图像。

结论

总之,我们优化应用程序的旅程展示了减少APK大小和优化内存的显着影响。这些努力不仅改善了用户体验,还为更高效的应用程序性能铺平了道路,使我们能够向客户交付更好,更快,更流畅的应用程序。

这篇关于65%更小的APK和70%更少的内存:如何优化我的Android App的内存的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/268234

相关文章

Vue3 的 shallowRef 和 shallowReactive:优化性能

大家对 Vue3 的 ref 和 reactive 都很熟悉,那么对 shallowRef 和 shallowReactive 是否了解呢? 在编程和数据结构中,“shallow”(浅层)通常指对数据结构的最外层进行操作,而不递归地处理其内部或嵌套的数据。这种处理方式关注的是数据结构的第一层属性或元素,而忽略更深层次的嵌套内容。 1. 浅层与深层的对比 1.1 浅层(Shallow) 定义

HDFS—存储优化(纠删码)

纠删码原理 HDFS 默认情况下,一个文件有3个副本,这样提高了数据的可靠性,但也带来了2倍的冗余开销。 Hadoop3.x 引入了纠删码,采用计算的方式,可以节省约50%左右的存储空间。 此种方式节约了空间,但是会增加 cpu 的计算。 纠删码策略是给具体一个路径设置。所有往此路径下存储的文件,都会执行此策略。 默认只开启对 RS-6-3-1024k

NameNode内存生产配置

Hadoop2.x 系列,配置 NameNode 内存 NameNode 内存默认 2000m ,如果服务器内存 4G , NameNode 内存可以配置 3g 。在 hadoop-env.sh 文件中配置如下。 HADOOP_NAMENODE_OPTS=-Xmx3072m Hadoop3.x 系列,配置 Nam

使用opencv优化图片(画面变清晰)

文章目录 需求影响照片清晰度的因素 实现降噪测试代码 锐化空间锐化Unsharp Masking频率域锐化对比测试 对比度增强常用算法对比测试 需求 对图像进行优化,使其看起来更清晰,同时保持尺寸不变,通常涉及到图像处理技术如锐化、降噪、对比度增强等 影响照片清晰度的因素 影响照片清晰度的因素有很多,主要可以从以下几个方面来分析 1. 拍摄设备 相机传感器:相机传

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo

Android平台播放RTSP流的几种方案探究(VLC VS ExoPlayer VS SmartPlayer)

技术背景 好多开发者需要遴选Android平台RTSP直播播放器的时候,不知道如何选的好,本文针对常用的方案,做个大概的说明: 1. 使用VLC for Android VLC Media Player(VLC多媒体播放器),最初命名为VideoLAN客户端,是VideoLAN品牌产品,是VideoLAN计划的多媒体播放器。它支持众多音频与视频解码器及文件格式,并支持DVD影音光盘,VCD影

MySQL高性能优化规范

前言:      笔者最近上班途中突然想丰富下自己的数据库优化技能。于是在查阅了多篇文章后,总结出了这篇! 数据库命令规范 所有数据库对象名称必须使用小写字母并用下划线分割 所有数据库对象名称禁止使用mysql保留关键字(如果表名中包含关键字查询时,需要将其用单引号括起来) 数据库对象的命名要能做到见名识意,并且最后不要超过32个字符 临时库表必须以tmp_为前缀并以日期为后缀,备份

SWAP作物生长模型安装教程、数据制备、敏感性分析、气候变化影响、R模型敏感性分析与贝叶斯优化、Fortran源代码分析、气候数据降尺度与变化影响分析

查看原文>>>全流程SWAP农业模型数据制备、敏感性分析及气候变化影响实践技术应用 SWAP模型是由荷兰瓦赫宁根大学开发的先进农作物模型,它综合考虑了土壤-水分-大气以及植被间的相互作用;是一种描述作物生长过程的一种机理性作物生长模型。它不但运用Richard方程,使其能够精确的模拟土壤中水分的运动,而且耦合了WOFOST作物模型使作物的生长描述更为科学。 本文让更多的科研人员和农业工作者

android-opencv-jni

//------------------start opencv--------------------@Override public void onResume(){ super.onResume(); //通过OpenCV引擎服务加载并初始化OpenCV类库,所谓OpenCV引擎服务即是 //OpenCV_2.4.3.2_Manager_2.4_*.apk程序包,存

从状态管理到性能优化:全面解析 Android Compose

文章目录 引言一、Android Compose基本概念1.1 什么是Android Compose?1.2 Compose的优势1.3 如何在项目中使用Compose 二、Compose中的状态管理2.1 状态管理的重要性2.2 Compose中的状态和数据流2.3 使用State和MutableState处理状态2.4 通过ViewModel进行状态管理 三、Compose中的列表和滚动