【Android】性能优化之内存、网络、布局、卡顿、安装包、启动速度优化
欢迎来到 Android 开发老生常谈的性能优化篇,本文将性能优化划分为内存、网络、布局、卡顿、安装包、启动速度七块,从这七块优化出发,阐述优化的 Application 的方式。
目录
- 内存优化
- 避免内存泄漏
- 使用内存分析工具
- 优化数据结构和算法
- 数据缓存
- 避免频繁的 GC
- 网络优化
- 合并接口请求,减少请求次数
- 使用网络缓存
- 使用合适的数据格式
- 使用合适的网络库
- 后台同步
- 预加载
- 使用持久连接
- 优化图片加载
- 使用前检测网络
- 布局优化
- 1、减少布局嵌套
- 2、减少 wrap-content 的使用
- 3、使用 include、merge、ViewStub,重复布局复用
- 卡顿优化
- 造成卡顿的原因
- 主线程阻塞
- 内存泄漏
- 布局过于复杂
- Bitmap对象过大
- 频繁的GC
- 动画效果处理不当
- 如何避免卡顿问题
- 避免在主线程中执行耗时操作
- 优化布局
- 处理内存泄漏
- 优化Bitmap的使用
- 减少GC的触发
- 安装包优化
- 资源优化
- 1、按需添加第三方库,避免引入重复库。
- 2、 png转svg,再使用svg转成vector格式。
- 3、 删除多余的so库。
- 4、 删除多余的 `mipmap` 文件夹。
- 5、 删除未使用到的资源文件。
- 6、动态加载.so文件。
- 7、使用插件化。
- 代码混淆
- 启动速度优化
- App Startup 优化初始化速度
- 懒加载
- ViewStup 按需加载布局
- Paging 分页
- ViewPager 2 翻页
- 预加载
- 伪加载
- 设置启动页
- 代码优化
- 使用 adb 命令查看启动 Activity 时间
- 使用 Profile 查看 Activity 方法耗时,对其进行优化
- WorkManager 后台保活
- 课外小知识
- 应用启动状态
- 冷启动
- 温启动
- 热启动
内存优化
在 Android 中,内存优化通常指的是 运行内存优化。运行内存优化 主要关注如何有效地使用和管理应用程序的 RAM (Random Access Memory) 使用,以提高性能,减少延迟,并防止应用程序因为消耗过多内存而被系统杀死。
避免内存泄漏
内存泄漏是指应用程序分配了内存,但未能释放。这会导致应用程序消耗的内存随着时间的推移而增加,可能导致应用程序崩溃或系统性能下降。
使用内存分析工具
Android Studio 提供了一些工具,如 Memory Profiler
,可以帮助开发者分析和理解应用程序的内存使用情况。
优化数据结构和算法
使用更有效的数据结构和算法可以减少内存使用。
数据缓存
合理使用 数据库、网络、图片缓存数据,可以减少不必要的数据、重复数据的存储,减少数据创建和销毁的开销,此外,还可以提高数据的访问速度。
避免频繁的 GC
垃圾回收 (Garbage Collection
简称 GC) ,频繁的垃圾回收会影响应用程序的性能。可以通过减少对象的创建和销毁,以及使用对象池等技术来减少垃圾回收的频率。
网络优化
合并接口请求,减少请求次数
尽可能地减少网络请求次数,可以通过合并请求、使用批量接口等方式实现。
使用网络缓存
对于一些不经常变动的数据,可以使用缓存来减少网络请求。例如,可以使用 HTTP
缓存、数据库缓存或者内存缓存。
使用合适的数据格式
例如,对于大量的数据,可以使用 Protobuf
而不是 JSON
,因为 Protobuf
更加紧凑,可以减少数据的大小,从而减少网络传输的时间。
使用合适的网络库
使用 OkHttp
、Retrofit
等网络库,它们内部已经做了很多优化。
后台同步
对于一些不需要立即返回结果的操作,可以使用后台同步,例如使用 WorkManager
或者 JobScheduler
。
预加载
对于一些用户可能需要的数据,可以提前进行加载。
使用持久连接
使用 HTTP2
,它们支持多路复用,可以减少连接的建立和关闭的开销。
优化图片加载
对于图片,可以使用合适的格式和大小,还可以使用图片加载库,例如 Glide
或者 Picasso
,它们内部已经做了很多优化。
使用前检测网络
在进行网络请求前,先检测网络状态,如果网络不可用,那么可以立即返回错误,而不是等待超时。
布局优化
1、减少布局嵌套
2、减少 wrap-content 的使用
3、使用 include、merge、ViewStub,重复布局复用
卡顿优化
在 Android 系统中,每一秒屏幕刷新速度为 60 帧(FPS),人类眼睛舒适放松时的可视帧率是 24 帧,当某个加载中的界面每秒刷新低于 24 帧时,就会感觉到卡顿。但当屏幕没有绘制需求时,即屏幕的显示的界面为静止时,帧率为 0。
造成卡顿的原因
主线程阻塞
如果在主线程(UI线程)中执行了耗时的操作,如网络请求、数据库操作等,会导致UI更新延迟,从而引发卡顿。
内存泄漏
如果应用中存在内存泄漏,可能会导致内存占用过高,从而引发卡顿。
布局过于复杂
如果布局层级过深或者布局过于复杂,可能会导致布局渲染时间过长,从而引发卡顿。
Bitmap对象过大
如果Bitmap对象过大,可能会导致内存占用过高,从而引发卡顿。
频繁的GC
垃圾回收 (Garbage Collection
简称 GC) 过程需要消耗系统资源,如果频繁触发,可能会导致应用性能下降,出现卡顿现象。
动画效果处理不当
如何避免卡顿问题
避免在主线程中执行耗时操作
可以使用线程、协程、AsyncTask等技术将耗时操作移至后台执行。
优化布局
尽量减少布局的层级,避免过度绘制,使用更高效的 View 或 ViewGroup。
处理内存泄漏
使用
LeakCanary
等工具帮助找到并处理内存泄漏。
优化Bitmap的使用
尽量不要使用过大的
Bitmap
,使用合适的压缩格式和分辨率,及时回收不再使用的Bitmap
。
减少GC的触发
尽量减少内存抖动,避免频繁的对象创建和销毁。 内存抖动 (
Memory Churn
) 是指应用程序在短时间内频繁地创建和销毁对象,这种行为会导致垃圾回收器 (Garbage Collector
) 频繁地运行,从而消耗大量的CPU资源,可能导致应用程序的性能下降,出现卡顿现象。
以上只是一些可能的原因,具体的原因需要通过性能分析工具如 Android Profiler
、BlockCanary
、Systrace
等进行分析。
往期文章👉【Android】测试方法汇总,助力打造完美应用
安装包优化
资源优化
1、按需添加第三方库,避免引入重复库。
2、 png转svg,再使用svg转成vector格式。
3、 删除多余的so库。
删除多余的so库,执行这一操作的前提是:程序所运行的系统 CPU 架构固定是 Android CPU 架构中的某一个。例如:部分第三方提供的 so 库是包含了 armeabi
、armeabi-v71
、arm64-v8a
、x86
等库文件,如果你的程序只运行在 armeabi
CPU 架构上,则可以把其它的 so 库文件删除。
4、 删除多余的 mipmap
文件夹。
一般图标资源使用 mipmap-xhdpi
足够用了,更大的屏幕则使用 mipmap-xxhdpi
、mipmap-xxxhdpi
的分辨率,已经使用 mipmap-xhdpi
或其它更大分辨率的程序,应删除比它小的分辨率文件。
5、 删除未使用到的资源文件。
可通过 Android Studio 菜单栏的 Refactor
→ Remove Unused Resources
功能一键移除未被使用的 drawable
、mipmap
、layout
以及 colors.xml
、strings.xml
文件里面的 color
、string
。
6、动态加载.so文件。
.so
文件可以在用户安装应用到手机后再从服务器上下载到手机的 data
目录下,加载的时候使用绝对路径在 static
关键字里加载。
static {System.loadLibrary("so文件")
}
参考文章
1、Android 应用资源概述
7、使用插件化。
插件化技术支持动态加载代码和动态加载资源,把 Application
的一部分分离出来,对于业务庞大的项目非常有用,极大的分解了 Application
的大小。但又因为插件化需要一定的技术保障和服务端的系统支持,有一定的风险,建议酌情选择。
代码混淆
代码混淆(Obfuscation)是将计算机程序的源代码或机器代码,转换成功能上等价,但是难于阅读和理解的形式的行为。简单来说,就是简化函数名、变量、常量名称,通过减少字符数以达到减小安装包大小的方式。
启用混淆只需要打开 Android 项目,在 Application Model 下中找到 build.gradle
,在该文件添加如下配置即可开启混淆:
android {// 打包 release 包时执行release {// 启用混淆,默认使用 R8 编译器minifyEnabled true// 资源压缩shrinkResources true// 定义 自定义混淆规则的文件proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'}}
}
上面混淆的方式仅适用于代码简单、封装少的项目。项目复杂还请自定义混淆规则,详情请查看往期文章👉【Android】App攻防之代码混淆
启动速度优化
App Startup 优化初始化速度
App Startup
是 Android 官方推出的一个应用程序启动时初始化组件的库。开发人员可以使用 App Startup
来简化启动序列并显式设置初始化顺序。
详情请看👉 App Startup
懒加载
懒加载是一种延迟加载的策略,它指的是在需要时才进行加载和初始化,而不是在应用程序启动或页面加载时就提前加载。这种策略通常用于延迟加载大型资源或组件,以减少启动时间和内存占用。
ViewStup 按需加载布局
详情请看👉 ViewStup
Paging 分页
详情请看👉 Paging
ViewPager 2 翻页
详情请看👉 ViewPager 2
预加载
预加载是在应用程序启动或特定页面加载之前提前加载和准备数据、资源或组件。这有助于提高应用程序的性能和响应速度,因为一些必要的内容已经被提前加载到内存中,而不是等到用户请求时再进行加载。
伪加载
伪加载是一种虚假的加载行为,通常用于模拟加载过程而不实际进行真正的加载。这种策略可以用于创建加载动画或展示加载状态,以提升用户体验,但实际上并没有进行真实的加载操作。
设置启动页
给 app 添加启动页,这应该是最常见的实现伪加载的方式了。当应用启动页播放完成跳转到首页时,你能很明显的感觉到,app 比没有使用启动页之前变得更“流畅”了。
设置启动页参考文章 👉 Android—启动页+闪屏页
其它启动速度优化的方法:
1、尽量不要在Application
的onCreate
中写初始化代码
2、减少静态类、静态方法、静态函数的使用,尽量做到用时再初始化
代码优化
使用 adb 命令查看启动 Activity 时间
在 Android 中,我们可以通过 adb
命令:adb shell am start -W packageName/packageName.ActivityName
获取到启动该 Activity
所消耗的时间,如下:
E:\Projects\StepDemo> adb shell am start -W com.binyouwei.demo/com.binyouwei.demo.MainActivityStarting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.binyouwei.demo/.MainActivity }
Status: ok
Activity: com.binyouwei.demo/.MainActivity
ThisTime: 522
TotalTime: 522
WaitTime: 525
Complete
在上方,我输入了 adb shell am start -W com.binyouwei.demo/com.binyouwei.demo.MainActivity
,系统给我响应了一大串的字符,其中的含义如下:
ThisTime
:指定的 activity 启动耗时。
TotalTime
:应用自身启动耗时 = ThisTime
+ 应用 Application
等资源启动时间
WaitTime
:系统启动应用耗时 = TotalTime
+ 系统资源启动时间
使用 Profile 查看 Activity 方法耗时,对其进行优化
使用参考文章👉Android Studio 中 CPU Profiler 系统性能分析工具的使用
WorkManager 后台保活
使用 WorkManager
实现后台保活,当应用处于后台时,应用所占的内存不会被系统完全回收,再次启动应用相较于第一次启动会更快。
课外小知识
应用启动状态
冷启动
冷启动是指应用程序从头开始启动的过程,这意味着应用程序的进程被终止,用户点击应用图标重新启动应用。在冷启动过程中,应用需要重新创建进程、初始化应用程序和加载 UI 界面。
温启动
温启动是指应用程序在后台保持活动状态并且重新进入前台时的启动方式。在温启动过程中,应用程序的进程仍然存在,但需要重新初始化和加载 UI 界面。
热启动
热启动是指应用程序在后台保持活动状态并且重新进入前台时的快速启动方式。在热启动过程中,应用程序的进程仍然存在,并且可以快速恢复到之前的状态,而不需要重新初始化和加载 UI 界面。
相关文章:
【Android】性能优化之内存、网络、布局、卡顿、安装包、启动速度优化
欢迎来到 Android 开发老生常谈的性能优化篇,本文将性能优化划分为内存、网络、布局、卡顿、安装包、启动速度七块,从这七块优化出发,阐述优化的 Application 的方式。 目录 内存优化避免内存泄漏使用内存分析工具优化数据结构和算法数据缓存…...
第3.6章:StarRocks数据导入——DataX StarRocksWriter
一、Datax 1.1 DataX 3.0概述 DataX3.0是一个异构数据源离线同步工具,可以方便的对各种异构数据源进行高效的数据同步。 其github地址为: https://github.com/alibaba/DataX/blob/master/introduction.mdhttps://github.com/alibaba/DataX/blob/mast…...
【非递归版】归并排序算法(2)
目录 MergeSortNonR归并排序 非递归&归并排序VS快速排序 整体思想 图解分析 代码实现 时间复杂度 归并排序在硬盘上的应用(外排序) MergeSortNonR归并排序 前面的快速排序的非递归实现,我们借助栈实现。这里我们能否也借助栈去…...
[C++]C++实现本地TCP通讯的示例代码
这篇文章主要为大家详细介绍了C如何利用TCP技术,实现本地ROS1和ROS2的通讯,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下 概要服务端代码 头文件源代码客户端代码 概要 利用TCP技术,实现本地ROS1和ROS2的通讯。 服务端代码 头文件 #include &…...
Sora - 探索AI视频模型的无限可能
文章目录 每日一句正能量前言技术解析应用场景未来展望伦理与创意用户体验与互动后记 每日一句正能量 . 一个人,如果没有经受过投资失败的痛楚,又怎么会看到绝望之后的海阔天空。很多时候,经历了人生中最艰难的事,反而锻造了最坚强…...
【JavaScript 漫游】【022】事件模型
文章简介 本篇文章为【JavaScript 漫游】专栏的第 022 篇文章,对 JavaScript 中事件模型相关的知识点进行了总结。 监听函数 浏览器的事件模型,就是通过监听函数(listener)对事件做出反应。事件发生后,浏览器监听到…...
【加密算法】RSA非对称加密算法简介
目录 前言 工作原理 密钥生成 加密和解密 在Java中使用RSA 生成密钥对 加密和解密数据 加密数据 解密数据 注意事项和最佳实践 结论 前言 RSA(Rivest-Shamir-Adleman)是一种基于数论的非对称加密算法,广泛应用于数字签名、数据加密…...
深入理解 JavaScript 对象原型,解密原型链之谜(上)
🤍 前端开发工程师、技术日更博主、已过CET6 🍨 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 🕠 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 🍚 蓝桥云课签约作者、上架课程《Vue.js 和 E…...
产品经理学习-产品运营《什么是SOP》
目录 什么是SOP 如何执行SOP 执行SOP的重点 什么是SOP SOP就是项目流程操作的说明书 日常工作中的例行操作: 例行操作是指,在每一天,针对每一个用户,在每个项目之中,都必须完成的操作,这些必须完成的操…...
大数据Hadoop生态圈
存储: HDFS(namenode,datanode) 计算:MapReduce(mapreduce,基于磁盘) 便于用sql操作:Hive(核心 metastore,存储这些结构化的数据),同类的还有Impala,hbase等 基于yaml的资源调度 hive &…...
算法简介:查找与算法运行时间
文章目录 1. 二分查找与简单查找1.1 运行时间 2. 旅行商问题 算法是一组完成任务的指令。任何代码片段都可以视为算法。 1. 二分查找与简单查找 二分查找是一种算法,其输入是一个有序的元素列表,如果要查找的元素包含在列表中,二分查找返回…...
零基础C++开发上位机--基于QT5.15的串口助手(三)
本系列教程本着实践的目的,争取每一节课都带大家做一个小项目,让大家多实践多试验,这样才能知道自己学会与否。 接下来我们这节课,主要学习一下QT的串口编程。做一款自己的串口助手,那么这里默认大家都是具备串口通信…...
Facebook的虚拟社交愿景:元宇宙时代的新起点
在当今数字化时代,社交媒体已经成为人们生活中不可或缺的一部分。而随着科技的不断进步和社会的发展,元宇宙已经成为了人们关注的热点话题之一。作为社交媒体的领军企业之一,Facebook也在积极探索虚拟社交的未来,将其视为元宇宙时…...
【深度学习笔记】4_6 模型的GPU计算
注:本文为《动手学深度学习》开源内容,部分标注了个人理解,仅为个人学习记录,无抄袭搬运意图 4.6 GPU计算 到目前为止,我们一直在使用CPU计算。对复杂的神经网络和大规模的数据来说,使用CPU来计算可能不够…...
留学申请过程中如何合理使用AI?大学招生官怎么看?
我们采访过的学生表示,他们在写essay的过程中会使用 ChatGPT,主要用于以下两个方面:第一,生成想法和头脑风暴;第二,拼写和语法检查。 纽约时报的娜塔莎辛格(Natasha Singer)在一篇文…...
vue2与vue3的diff算法有什么区别
在 Vue 中,虚拟 DOM 是一种重要的概念,它通过将真实的 DOM 操作转化为对虚拟 DOM 的操作,从而提高应用的性能。Vue 框架在虚拟 DOM 的更新过程中采用了 Diff 算法,用于比较新旧虚拟节点树,找出需要更新的部分ÿ…...
ES小总结
组合查询 FunctionScoreQueryBuilder functionScoreQuery QueryBuilders.functionScoreQuery(boolQuery,new FunctionScoreQueryBuilder.FilterFunctionBuilder[]{new FunctionScoreQueryBuilder.FilterFunctionBuilder(QueryBuilders.termQuery("isAD",true),Score…...
vue2与vue3中父子组件传参的区别
本次主要针对vue中父子组件传参所进行讲解 一、vue2和vue3父传子区别 1.vue2的父传子 1).在父组件子标签中自定义一个属性 <sonPage :子组件接收到的类名"传输的数据">子组件</sonPage> 2).在子组件中peops属性中拿到自定属性 props: {子组件接收的…...
使用vuetify实现全局v-alert消息通知
前排提示,本文为引流文,文章内容不全,更多信息前往:oldmoon.top 查看 简介 使用强大的Vuetify开发前端页面,结果发现官方没有提供简便的全局消息通知组件(像Element中的ElMessage那样)…...
CentOS 7.9上编译wireshark 3.6
工作环境是Centos 7.9,原本是通过flathub安装的wireshark,但是在gnome的application installer上升级到wireshark 4.2.3之后就运行不起来了,flatpak run org.wireshark.Wireshark启动提示缺少qt6,查了一下wireshark新版是依赖qt6的…...
初学学习408之数据结构--数据结构基本概念
初学学习408之数据结构我们先来了解一下数据结构的基本概念。 数据结构:是相互之间存在一种或多种特定关系的数据元素的集合。 本内容来源于参考书籍《大话数据结构》与《王道数据结构》。除去书籍中的内容,作为初学者的我会尽力详细直白地介绍数据结构的…...
Java项目中必须使用本地缓存的几种情况
Java项目中必须使用本地缓存的几种情况 在Java项目的开发过程中,为了提高应用的性能和响应速度,缓存机制经常被使用。其中,本地缓存作为一种常见的缓存方式,将数据存储在应用程序的本地内存或磁盘中,以便快速访问。下…...
【鸿蒙 HarmonyOS 4.0】TypeScript开发语言
一、背景 HarmonyOS 应用的主要开发语言是 ArkTS,它由 TypeScript(简称TS)扩展而来,在继承TypeScript语法的基础上进行了一系列优化,使开发者能够以更简洁、更自然的方式开发应用。值得注意的是,TypeScrip…...
Android java基础_异常
一.异常的概念 在Java中,异常(Exception)是指程序执行过程中可能出现的不正常情况或错误。它是一个事件,它会干扰程序的正常执行流程,并可能导致程序出现错误或崩溃。 异常在Java中是以对象的形式表示的,…...
高数考研 -- 公式总结(更新中)
1. 两个重要极限 (1) lim x → 0 sin x x 1 \lim _{x \rightarrow 0} \frac{\sin x}{x}1 limx→0xsinx1, 推广形式 lim f ( x ) → 0 sin f ( x ) f ( x ) 1 \lim _{f(x) \rightarrow 0} \frac{\sin f(x)}{f(x)}1 limf(x)→0f(x)sinf(x)1. (2) lim …...
详解顺序结构滑动窗口处理算法
🎀个人主页: https://zhangxiaoshu.blog.csdn.net 📢欢迎大家:关注🔍点赞👍评论📝收藏⭐️,如有错误敬请指正! 💕未来很长,值得我们全力奔赴更美好的生活&…...
Java 8中使用Stream来操作集合
Java 8中使用Stream来操作集合 在Java 8中,你可以使用Stream API来操作集合,这使得集合的处理变得更加简洁和函数式。Stream API提供了一系列的中间操作(intermediate operations)和终端操作(terminal operations&…...
MATLAB环境下一种改进的瞬时频率(IF)估计方法
相对于频率成分单一、周期性强的平稳信号来说,具有非平稳、非周期、非可积特性的非平稳信号更普遍地存在于自然界中。调频信号作为非平稳信号的一种,由于其频率时变、距离分辨率高、截获率低等特性,被广泛应用于雷达、地震勘测等领域。调频信…...
解决:selenium web browser 的版本适配问题
文章目录 解决方案:使用 webdriver manager 自动适配驱动 使用 selenium 操控浏览器的时候报错: The chromedriver version (114.0.5735.90) detected in PATH at /opt/homebrew/bin/chromedriver might not be compatible with the detected chrome ve…...
pytest.param作为pytest.mark.parametrize的参数进行调用
pytest.param:在 pytest.mark.parametrize 中可以作为一个指定的参数进行调用 获取数据库(网页端)数据,通过pytest.param包装成数据包用于pytest.mark.parametrize 中实现数据驱动调用。 import os import pytest import json fr…...
做微信表情的微信官方网站/搜索引擎营销方案
网址:http://cmder.net/ 如果vim乱码 命令行输入 set LC_ALLzh_CN.UTF8 添加cmder到鼠标右键 c://安装目录/Cmder.exe /REGISTER ALL 右键添加 Cmder here 选项 我们首先需要通过原来的cmd来到Cmder的目录下,然后运行相关的指令: Cmder.exe /REGISTER…...
网络销售推广平台/seo最新技巧
一个朋友是前阿里人,37岁,离职后就职美团。以前投一个面一个,今年想跳槽,但没想到投十个能有两个面试机会就不错了,最后索性又回了阿里做架构。 他在面试的时候,碰见比自己大的面试官,态度和善&…...
一个在线做笔记的网站/百度如何做广告
一、操作系统提代一个开发接口给硬件开发商,让他们可以根据这个接口设计可以驱动他们硬件的驱动程序。二、应用程序是参考操作系统提供开发接口所开发出来的软件三、核心功能:系统呼叫接口、程序管理、内存管理、文件系统管理、装置驱动四、CPU每次能够处…...
网站怎么做的支付宝接口/网络营销专业是干什么的
文|曾响铃 来源|科技向令说(xiangling0815) 元旦已过,眼看农历新年马上来临,又到了一年一度“囤货”的季节。有一类产品的“热度”从2019年春节期间,一直延续至今,那就是水果。 在2019年春节期间&#x…...
深圳网站建设网络推广公司/百度关键词推广价格
1. find /test ! -name "test" -type d -prune -o -type f -name "*.txt" -print 查找/test下的.txt的普通文件,不查找子目录。 2. find . ! -name "." -type d -prune -o -type f -print 查找当前目录下的普通文件,不查找…...
wordpress媒体库不能用云/站长工具最近查询
之前我们讨论过《Linux Oracle 11g dataguard物理standby 配置过程》, 但是在实际过程中会遇到不同的问题,首先我们讨论下ORACLE DATA…...