百度360必应搜狗淘宝本站头条
当前位置:网站首页 > IT技术 > 正文

想要深入学习Android性能优化?看完这篇直接让你一步到位

wptr33 2025-04-11 08:28 48 浏览

Android性能优化

Android中的性能优化基本上可以分为以下几个方面:

● 布局优化

● 网络优化

● 内存优化

● 卡顿优化

● 启动优化

布局优化

Android的布局管理器本身就是个UI组件; 所有的布局管理器都是ViewGroup的子类,而ViewGroup是View的子类,所以布局管理器可以当成普通的UI组件使用,也可以作为容器类使用,可以调用多个重载addView()向布局管理器中添加组件,并且布局管理器可以互相嵌套;当然不推荐过多的嵌套 (兼容低端机型,最好不要超过5层)

布局层级管理

让咱们一起了解一下每当系统绘制一个布局时,都会发生一些什么; 这一过程由两个步骤完成:

绘制(Measurement)

● 根布局测量自身

● 根布局要求它内部所有子组件测量自身

● 所有自布局都需要让它们内部的子组件完成这样的操作,直到遍历完视图层级中所有的View

摆放(Positioning)

● 当布局中所有的View都完成了测量,根布局则开始将它们摆放到合适的位置

● 所有子布局都需要做相同的事情,直到遍历完视图层级中所有的View

当某个View的属性发生变化(如:TextView内容变化或ImageView图像发生变化),View自身会调用View.invalidate()方法(必须从 UI 线程调用),自底向上传播该请求,直到根布局(根布局会计算出需要重绘的区域,进而对整个布局层级中需要重绘的部分进行重绘)

布局层级越复杂,UI加载的速度就越慢。因此,在编写布局的时候,尽可能地扁平化是非常重要的

FrameLayout和TableLayout有各自的特殊用途,LinearLayout 和 RelativeLayout 是可以互换的,ConstraintLayout和RelativeLayout类似

也就是说,在编写布局时,可以选择其中一种,也可以用不同的方式来编写布局

网络优化

网络优化的三个要点

多维

● 网络优化应该是多维的,一般情况下,一谈到网络优化,大部分人首先想到的就是流量消耗,但是实际上流量消耗多少只是网络优化的其中一个维度

● 只对流量消耗一个维度进行优化是不够的,甚至有的团队即便在流量优化上也没有做好,比如对于网络流量的消耗统计不够全面和精确

精准

● 在做网络流量统计时,我们要做精准度量,如果只是获取了具体消耗了多少的值,对于我们定位和解决问题是没有太大的帮助,因为这个值只能表明用户用了多少流量

● 如果线上用户反馈 App 消耗流量较多,但是我们不知道这个用户总共使用了 App 多长时间的话,那就不好定位问题所在,如果用户使用 App 的时间比较长,那消耗流量多一些很可能是正常的

● 又比如用户反馈 App 在后台消耗流量比较多,但是我们只统计了整体的值,那就无法断定 App 在后台运行时到底消耗了多少流量

监控

● 针对网络优化,我们应该建设全面且完善的网络监控体系,不能只监控一个指标,假如只监控网络请求成功率,那我们就只能知道用户大概的网络使用情况,这种粗粒度的监控没办法帮助我们找出并解决问题的根源

● 比如线上用户使用了某个功能使用了 1000 次,然后出现了 1 次异常,而且用户点击重试后就恢复正常了

● 这样单从数据上来看的话,网络请求的成功率还是比较高的,但是只通过成功率一个值是无法知道这一次异常出现的原因,也就无法避免后续出现这类异常

网络优化的两个维度

流量维度

● 流量维度也就是 App 在一段时间内流量消耗的精准度量

● 流量消耗大不仅对用户有影响,对公司的运营成本也有影响,比如带宽、服务器数量、CDN 等方面的开支,而且网络请求密集对手机耗电量也有一定的影响

● 在流量维度上,我们要做到区分类型、监控异常、上报日志

区分类型

● 我们不仅要知道用户在某个时间段内的具体流量消耗,还要知道用户在不同网络类型(流量、WiFi)下的流量消耗、区分 App 在前台和在后台时的流量消耗

● 只有积累了不同维度的数据,才能快速断定和解决问题

监控异常

对于流量统计,我们不仅要知道用户的流量消耗均值,还要知道线上用户消耗流量的异常率。

这里的异常分为三种:

● 流量消耗过多

● 请求次数过多

● 下载文件过大

这三个都是我们要注意的异常

上报日志

● 最理想的情况,就是我们对所有的网络请求,在本地都有一个完整的监控,每一个请求的 Request 和 Response 相关的所有信息都全部记录下来

● 服务端可以下发指令控制客户端上传这些数据,客户端也可以在相关数据超过阈值后主动上报

质量维度

网络请求的质量也非常关键,它直接对应了用户的真实体验,如果网络请求速度慢或请求成功率比较低,都会导致不好的用户体验

对于网络请求质量的监控,可以从下面几个维度进行区分,以便后续能快速定位和解决问题

● 请求时长

● 请求成功率

● 失败率

● Top 失败接口

网络优化的两个误区

只关注流量

● 只关注流量消耗,忽视了其他维度

忽略个体数据

● 还有就是做网络监控时只关注均值和整体的数据,忽略了个体的数据

● 比如前面提到的请求成功率的例子,从整体上来看成功率非常高,但是这种数据无法帮助我们改善单次请求

● 做内存优化的目的是降低OOM率、减少卡顿、增加应用存活时间

内存优化

降低OOM

● 做内存优化的一个常见原因是为了降低OOM率 申请内存过多而没有及时释放,常常就会导致OOM 引起OOM的原因有多种,在后面我们再细谈

减少卡顿

Android中造成界面卡顿的原因有很多种,其中一种就是由内存问题引起的. 内存问题之所以会影响到界面流畅度,是因为垃圾回收. 在GC时,所有线程都要停止,包括主线程.当GC和绘制界面的操作同时触发时,绘制的执行就会被搁置,导致掉帧,也就是界面卡顿

增加应用存活时间

Android会按照特定的机制清理进程,清理进程时优先会考虑清理后台进程,如果某个应用在后台运行并且占用的内存更多,就会被优先清理掉 我们通常希望App能尽量存活的久一点,所以内存不再使用时应该尽快释放

导致卡顿的因素

● 硬件因素:CPU、RAM、ROM、HeapSize、SDK Version

● 软件因素:UI渲染相关、UI线程操作相关

卡顿优化

如何定义发生了卡顿现象:

● 如果App的FPS平均值小于30,最小值小于24,即表明应用发生了卡顿

● 线下很难复现,与发生场景强相关(所以需要我们去做卡顿监控,收集现场信息)

CPU相关知识

● 现在最新的主流机型都使用了多级能效的CPU架构(即多核分层架构)

● 从 CPU 到 GPU 再到 AI 芯片NPU,随着手机 CPU 整体性能的飞跃, 我们可以充分利用移动端的计算能力来降低高昂的服务器成本

● 评价一个 CPU 的性能,需要看主频、核心数、缓存等参数,具体表现出来的是计算能力和指令执行能力,也就是每秒执行的浮点计算数和每秒执行的指令数

● 造成卡顿的原因很多(涉及到代码、内存、绘制、IO、CPU等),最终都反映到 CPU 时间上; CPU时间 可以分为用户时间和系统时间:

● 用户时间:执行用户态应用程序代码所消耗的时间

● 系统时间:执行内核态系统调用所消耗的时间,包括 I/|O、锁、中断以及其他系统调用的时间

CPU相关的三类问题

CPU资源冗余使用:

● 算法效率低

● 没使用缓存

● 计算时使用的基本类型不对(如int足够却用long,运算压力多出4倍)

CPU资源争抢:

● 抢主线程的CPU资源

● 抢音视频的CPU资源

● 编解码本身会消耗大量的CPU资源,并且其对于解码的速度是有硬性要求的,如果达不到就可能产生播放流畅度的问题

采取两种方式去优化:

● 尽量排除非核心业务的消耗

● 优化自身的性能消耗,把CPU负载转化为GPU负载,如使用renderscript来处理视频中的影像信息

大家平等,互相抢(三个和尚没水喝)

CPU资源利用率低:

● 有磁盘和网络I/O,还有锁操作、sleep等等, 对于锁的优化,通常是尽可能地缩减锁的范围

启动优化

网上流行一种说法,就是8秒定律,意思是说,如果用户在打开一个页面,在8秒的时间内还没有打开,那么用户大概的会放弃掉,意味着一个用户的流失。从这里就可以看出,启动优化的重要性了

启动的分类

冷启动

先来看看冷启动的流程图:

从图中可以看出,APP启动的过程是:ActivityManagerProxy 通过IPC来调用AMS(ActivityManagerService),AMS通过IPC启动一个APP进程,ApplicationThread通过反射来创建Application并且绑定,最后通过ActivityThread来控制activity的生命周期,在相关页面的生命周期中通过ViewRootImpl来对view的实现;从而完成应用的启动

热启动

热启动的速度是最快的,它就是进程从后台切换到前台的一个过程。

温启动

温启动只会重新走一遍页面的生命周期,但是对于进程,application不会重新在创建。

优化方向

上面介绍了启动的几种方式可以看出,我们针对启动优化,基本只是优化冷启动就可以了。但是从冷启动的启动流程中很多都是系统做的,我们没有办法操控。我们能做的,就是application的生命周期和activity的生命周期这部分,启动优化往往就是从这两块入手。

优化总结

性能优化是我们进阶的必经之路

所以,我们必须要会,至于“会”到什么程度,就要看个人理解了

其实,上面介绍的只是性能问题的冰山一角,真正的优化,我们是在项目中总结出来的;但,我们不能一味的追求优化,就例如我,现在只是在进行优化的总结,而对于真正的实行,并没有开始,因为,优化是有风险的,一个不小心,整个项目都可能炸了

所以这就需要你的经验,以及各种总结,在改进行优化的地方先进行优化,看看效果如何,例如,UI的优化以及代码的优化

可以先拿一些网上的开源项目进行优化等等

也可以私信发送 “笔记“ “进阶” 获取更多 Android学习笔记

相关推荐

oracle数据导入导出_oracle数据导入导出工具

关于oracle的数据导入导出,这个功能的使用场景,一般是换服务环境,把原先的oracle数据导入到另外一台oracle数据库,或者导出备份使用。只不过oracle的导入导出命令不好记忆,稍稍有点复杂...

继续学习Python中的while true/break语句

上次讲到if语句的用法,大家在微信公众号问了小编很多问题,那么小编在这几种解决一下,1.else和elif是子模块,不能单独使用2.一个if语句中可以包括很多个elif语句,但结尾只能有一个else解...

python continue和break的区别_python中break语句和continue语句的区别

python中循环语句经常会使用continue和break,那么这2者的区别是?continue是跳出本次循环,进行下一次循环;break是跳出整个循环;例如:...

简单学Python——关键字6——break和continue

Python退出循环,有break语句和continue语句两种实现方式。break语句和continue语句的区别:break语句作用是终止循环。continue语句作用是跳出本轮循环,继续下一次循...

2-1,0基础学Python之 break退出循环、 continue继续循环 多重循

用for循环或者while循环时,如果要在循环体内直接退出循环,可以使用break语句。比如计算1至100的整数和,我们用while来实现:sum=0x=1whileTrue...

Python 中 break 和 continue 傻傻分不清

大家好啊,我是大田。今天分享一下break和continue在代码中的执行效果是什么,进一步区分出二者的区别。一、continue例1:当小明3岁时不打印年龄,其余年龄正常循环打印。可以看...

python中的流程控制语句:continue、break 和 return使用方法

Python中,continue、break和return是控制流程的关键语句,用于在循环或函数中提前退出或跳过某些操作。它们的用途和区别如下:1.continue(跳过当前循环的剩余部分,进...

L017:continue和break - 教程文案

continue和break在Python中,continue和break是用于控制循环(如for和while)执行流程的关键字,它们的作用如下:1.continue:跳过当前迭代,...

作为前端开发者,你都经历过怎样的面试?

已经裸辞1个月了,最近开始投简历找工作,遇到各种各样的面试,今天分享一下。其实在职的时候也做过面试官,面试官时,感觉自己问的问题很难区分候选人的能力,最好的办法就是看看候选人的github上的代码仓库...

面试被问 const 是否不可变?这样回答才显功底

作为前端开发者,我在学习ES6特性时,总被const的"善变"搞得一头雾水——为什么用const声明的数组还能push元素?为什么基本类型赋值就会报错?直到翻遍MDN文档、对着内存图反...

2023金九银十必看前端面试题!2w字精品!

导文2023金九银十必看前端面试题!金九银十黄金期来了想要跳槽的小伙伴快来看啊CSS1.请解释CSS的盒模型是什么,并描述其组成部分。答案:CSS的盒模型是用于布局和定位元素的概念。它由内容区域...

前端面试总结_前端面试题整理

记得当时大二的时候,看到实验室的学长学姐忙于各种春招,有些收获了大厂offer,有些还在苦苦面试,其实那时候的心里还蛮忐忑的,不知道自己大三的时候会是什么样的一个水平,所以从19年的寒假放完,大二下学...

由浅入深,66条JavaScript面试知识点(七)

作者:JakeZhang转发链接:https://juejin.im/post/5ef8377f6fb9a07e693a6061目录由浅入深,66条JavaScript面试知识点(一)由浅入深,66...

2024前端面试真题之—VUE篇_前端面试题vue2020及答案

添加图片注释,不超过140字(可选)1.vue的生命周期有哪些及每个生命周期做了什么?beforeCreate是newVue()之后触发的第一个钩子,在当前阶段data、methods、com...

今年最常见的前端面试题,你会做几道?

在面试或招聘前端开发人员时,期望、现实和需求之间总是存在着巨大差距。面试其实是一个交流想法的地方,挑战人们的思考方式,并客观地分析给定的问题。可以通过面试了解人们如何做出决策,了解一个人对技术和解决问...