首页 > 其他分享 >Android性能优化总结

Android性能优化总结

时间:2023-04-05 18:35:44浏览次数:39  
标签:总结 优化 布局 内存 GPU Android 绘制 View


这是来自一位粉丝「MeloDev」的投稿,讲真,我这里投稿的不少,但是只有我自己觉得很不错的才会通过,这篇文章我觉得对大家有用,而且性能优化也算是我面试必问的一个话题了,所以这里推荐给大家。微信不支持链接,可点击「阅读原文」查看原文。


写在前面

公司给了我一周的时间去学习Android性能的优化,参考了张明云老师的一片文章,并且用公司的实际项目进行测试(附有截图),还进行了一些知识点,注意事项以及很多网址链接的补充,希望这篇博文能让做性能测试的朋友们少走一些弯路。

文中没有贴出大段代码,但是几乎所有的知识点都有链接,点进去就能看你想看的。转载注明出处。

性能指标

1. 布局复杂度:布局复杂会导致布局需要更长的时间,从而导致进入应用慢、页面切换慢;

2. 耗电量:耗电量大会导致机器发热、缩短机器的有效使用时长;

3. 内存:内存消耗大会导致频繁GC,GC时会暂停其它工作,导致页面卡顿;内存泄露会导致剩余可用内存越来越小;内存不足会导致应用异常;

4. 网络:频繁的网络访问会导致耗电和影响应用的性能;网络交互数据大小会影响网络传输的效率;

5. 程序执行效率:糟糕的代码会严重影响程序的运行效率,UI线程过多的任务会阻塞应用的正常运行,长时间持有某个对象会导致潜在的内存泄露,频繁的IO操作、网络操作而不用缓存会严重影响程序的运行效率。

一、布局复杂度的优化

关于布局的优化,主要分两个大方向

1. 实现相同界面效果并且层级结构相同时,选用何种Layout最好

在Android中单独的布局性能:

FrameLayout>LinearLayout>RelativeLayout

可供参考的网址:「LinearLayout与RelativeLayout的性能比较」 


总结:

  • RelativeLayout会让子View调用2次onMeasure,LinearLayout 在有weight时,也会调用子View2次onMeasure;
  • RelativeLayout的子View如果高度和RelativeLayout不同,则会引发效率问题,当子View很复杂时,这个问题会更加严重。如果可以,尽量使用padding代替margin;
  • 在不影响层级深度的情况下,使用LinearLayout和FrameLayout而不是RelativeLayout;
  • 使用组合控件性能要好于两个独立控件,比如一个文本旁边有一个图片,这中情况最好要用DrawableLeft的这种属性设置图片;


2. 减少布局的层级结构

  • HierarchyViewer—可查看布局层次结构,View绘制时耗时。 

「HierarchyViewer的使用」

  • 无线UIViewer—强烈推荐App工具,可在手机端直接实现HierarchyViewer的功能,查看任意界面的UI布局。 

「无线UIViewer下载」

测试图片如下: 

Android性能优化总结_UI

当前界面的UI布局层级如上图所示

总结:

  • 一些复用性很高的布局文件,比如一个App的标题栏,建议使用布局重用include标签,方便引入和共同管理。
  • 观察上图第三个层级和第四个层级,无论是Layout类型,还是所覆盖的坐标点,都是重合的,因为父FrameLayout作为一个Container,子FrameLayout作为一个子View的跟布局,这种情况,可使用merge标签进行布局层级的优化。
  • 有些在特定情况下才会出现的界面,比如联网之后,或者未必百分之百出现的界面,可用ViewStub标签进行懒加载,性能明显要优于加载出这个界面然后gone掉。

布局优化相关网址: 

「三种优化标签的使用情景和优势—张业兴 」

「布局优化标签的源码分析」

有关布局优化的一些基础知识准备(郭霖老师的两篇博客): 

「Android LayoutInflater原理分析,带你一步步深入了解View(一) 」

「Android视图绘制流程完全解析,带你一步步深入了解View(二)」

二、Android开发者模式—GPU过渡绘制

GPU过度绘制定义:

如果你粉刷过一个房间或一所房子,就会知道给墙壁涂上颜色需要做大量的工作。假如你还要重新粉刷一次的话,第二次粉刷的颜色会覆盖住第一次的颜色,第一次的颜色就永远不可见了,等于你第一次粉刷做的大量工作就完全被浪费掉。这太可怕了。

同样的道理,如果在你的应用程序中浪费精力去绘制一些东西同样会产生性能问题。过度绘制这个名词就是用来描述屏幕上一个像素在单个帧中被重绘了多少次。

GPU过度绘制就指的是在屏幕一个像素上绘制多次(超过一次),GPU过度绘制或多或少对性能有些影响。

GPU过度绘制分析:

过度绘制其实是一个性能和设计的交叉点。我们在设计上追求很华丽的视觉效果,但一般来说这种视觉效果会采用非常多的层叠组件来实现,这时候就会带来过度绘制的问题。我们再来看看具体显示在Android界面层级关系:

当我们来绘制一个界面时,会有一个windows,然后是建立Activity,在Activity里可以建立多个view,或view group,view也可以嵌套view。这些组件从上到下分布,上面的组件是可以被用户看见的,而在下面的组件是不可见的,但是我们依然要花很多时间去绘制那些不可见的组件,因为在某些时候,它也可能会显示出来。

检测过度绘制:

设置-开发者选项-调试GPU过度绘制-显示过度绘制区域(过度渲染等,不同机器可能不同)

Android性能优化总结_UI_02

测试的颜色标识含义:

Android性能优化总结_UI_03

项目测试截图:

Android性能优化总结_UI_04

Android性能优化总结_Android_05

Android性能优化总结_加载_06

可以看到项目中并不存在太大问题,有关减少过度绘制的一些建议:

1. 太多重叠的背景

这个问题其实最容易解决,建议前期在设计时尽量保持整体背景统一,另外开发可以检查你在布局和代码中设置的背景,有些背景是被隐藏在底下的,它永远不可能显示出来,这种没必要的背景一定要移除,因为它很可能会严重影响到app的性能。

2. 太多重叠的view

第一个建议是:使用ViewStub来加载一些不常用的布局,它是一个轻量级且默认不可见的视图,可以动态的加载一个布局,只有你用到这个重叠着的view的时候才加载,推迟加载的时间。第二个建议是:如果使用了类似viewpager+Fragment这样的组合或者有多个Fragment在一个界面上,需要控制Fragment的显示和隐藏,尽量使用动态地Inflation view,它的性能要比SetVisiblity好。

3. 复杂的Layout层级

这里的建议比较多一些,首先推荐用Android提供的布局工具Hierarchy

三、Android中耗电量的测试

「深入浅出Android App耗电量统计」

测试截图:

Android性能优化总结_加载_07

本人认为这一点没有过多补充的,大多数App都不会消耗过多的电量。

四、内存、CPU、GPU

应用运行时内存使用情况查看:Android Studio—Memory/CPU/GPU

通常这种测试应该使用一个自动化工具(monkey)去不停的点击App,或者切换界面,来观察内存、cpu的情况。

1. 内存

测试截图:

Android性能优化总结_UI_08

在地图界面不断地刷新,正常的内存成锯齿状分布。

需要注意的情况:

Android性能优化总结_Android_09

出现了针状分布,说明内存发生了突变,如果内存峰值不能降下来,就说明出现了内存溢出,就值得引起我们的关注了。

2. CPU

测试图片:

Android性能优化总结_加载_10

3. GPU

Android Studio 1.4增加一项新功能:分析GPU渲染功能。作者详细讲解这一新功能的分析方法。

在GPU选项卡下,可以在屏幕上看到图形化显示的渲染每帧所花费的时间。图形中每条都表示被渲染的一帧。颜色表示进程的不同周期:

绘画(蓝色) 

表示View#onDraw()方法。那部分建立/更改DisplayList对象,然后转换成GPU能够理解的OpenGL命令。高的条形可能是视图复杂,而要求更多的时间绘制它们的显示列表,而许多视图在短时间内就失效了。

准备(紫色) 

在Lollipop中,加入另一个线程,以帮助UI线程渲染更快。这个线程叫:RenderThread。它的责任是转换显示列表为OpenGL命令,再发送给GPU。这样在渲染过程中,UI线程可以开始处理下一个帧。这时UI线程将所有资源传送给RenderThread。如果有许多资源要传递(如许多/繁重显示列表),这一步可能需要较长时间。

处理(红色) 

执行显示列表产生OpenGL命令。由于需要视图重绘,如果有许多/复杂显示列表要执行转换,这一步可能需要较长时间。当视图无效或是移动时,都要要重绘视图。

执行(黄色) 

发送OpenGL命令到GPU。由于CPU发送这些缓存的命令到GPU,并期待收回干净缓存,这就阻塞调用了。缓存数量有限,并且GPU也很忙 

—— 

CPU会发现自己必须先等待缓存释放。因此,如果在这一步我们见高的条形,就可能意味着GPU在绘制UI时非常忙,这个绘制在短时间内太复杂了。

测试截图: 

Android性能优化总结_Android_11

结论:

可以通过切换界面,看图形的峰值和颜色去判断绘制View每个阶段所花费的时间,然后根据你的需求进行优化。

五、程序的执行效率

  • 静态代码检查工具:Android studio—Analyze—Inspect Code…/Code cleanup… ,用于检测代码中潜在的问题、存在效率问题的代码段并提供改善方案;
  • DDMS—TraceView,用于查找程序运行时具体耗时在哪;
  • StrictMode:用于查找程序运行时具体耗时在哪,需要集成到代码中;

六、知名的三方性能优化工具

1. LeakCanary 

LeakCanary是一个检测内存泄露的开源类库。你可以在 debug 

包种轻松检测内存泄露。强烈推荐LeakCanary,大多数公司都在使用它进行内存泄漏的测试。

以下是我找到的学习资料,写的非常棒:

「LeakCanary: 让内存泄露无所遁形」

「LeakCanary 中文使用说明」

具体使用请参考以上两个链接,下面给出一个测试截图,供大家直观感受其便捷和强大的功能。

Android性能优化总结_UI_12

Android性能优化总结_UI_13

结论: LeakCanary非常直观的展现了MainActivity出现了内存泄漏,并且指出引用路径中的哪个引用是不该有的,然后修复问题。总而言之非常好用,处理内存泄漏首选的工具。

2. GT 

GT是腾讯开发的一款APP的随身调测平台,利用GT,可以对CPU、内存、流量、点亮、帧率/流畅度进行测试,还可以查看开发日志、crash日志、抓取网络数据包、APP内部参数调试、真机代码耗时统计等等,需要说明的是,应用需要集成GT的sdk后,GT这个apk才能在应用运行时对各个性能进行检测。

「GT官方网址」

下面是使用GT测试项目的截图:

Android性能优化总结_Android_14

Android性能优化总结_加载_15

Android性能优化总结_UI_16

Android性能优化总结_加载_17

Android性能优化总结_UI_18

具体图片是什么含义,大家去点击官网去了解学习就可以,GT还是很全面好用的,慢慢发掘吧。

标签:总结,优化,布局,内存,GPU,Android,绘制,View
From: https://blog.51cto.com/stormzhang/6171275

相关文章

  • Android开发如何进阶?
    本着每周至少有干货产出的原则,今天必须写篇干货来回馈大家,我这的干货可是不收费的哦,争取以后的目标是让你们看完我的文章不赞赏都觉得亏得慌!之前不少人都问我同一个问题,就是我学习Android有一两年了,但是遇到瓶颈了,感觉没什么进步,到底怎么才能进阶呢?我相信有不少人遇到这样的困扰,那......
  • Android 还可以走多久?
    阅读文本大概需要1.8分钟。最近,有位知识星球的球友问我这么一个问题:「张哥,我做Android开发两年多时间了,但是最近总是很焦虑,看着人工智能越来越火,很担心Android要不行了,想问下,我现在要转行么?Android还可以走多久?」这个问题我觉得还蛮有代表性的,今天就姑且给大家谈谈这个话题......
  • 近期学习总结
    近期C语言课堂学习总结学习中遇到的小山们序号困难1用%f或者按照宽度取位数时会四舍五入,如果要不四舍五入直接按照位数取数字的话暂时不知道怎么实现2经常碰见不同类型的值不能进行运算的情况,暂时记不清哪些地方不能3有的时候不会一些算法,比如一些公式的表达,......
  • 2012总结--第8篇--感情篇
    1.亲情家人2012年春上离开家里后,还没有回去过。只是偶尔给家里打个电话。家人倒是希望我早点回去。不知道为什么,我总有种“不成就一番伟业不回家"的感觉。这个儿子白养了”。这话太犀利了。无言以对!沉默!至亲家人没有见到,其他亲人就更不用说了。只是和......
  • 一个Web报表项目的性能分析和优化实践(六):设置MySQL的最大连接数(max_connections)
    在上一篇文章中"一个Web报表项目的性能分析和优化实践(二):MySQL数据库连接不够用(TooManyConnections)问题的一次分析和解决案例"提到,项目中新增几个数据库后,数据库最大连接数达到了默认的最大值100。此时,如果再创建连接,就会报错(TooManyConnections)。因此,需要手动设置MySQL的最......
  • 一个Web报表项目的性能分析和优化实践(四):MySQL建立索引,唯一索引和组合索引
    先大致介绍下项目的数据库信息。数据库A:主要存放的通用的表,如User、Project、Report等。数据库B、C、D:一个项目对应一个数据库,而且这几个项目的表是完全一样的。数据库表的特点A中的表:数据量几乎都比较小,比如User表中用户数,顶多也就几百上千。B中的表:X/Y/Z3张表几乎是确定的,Data表......
  • 2012总结--第7篇--财务篇
    特别说明:1.Fans比较节省,有少量积蓄,但Fans想说的:Fans辛辛苦苦攒钱既不是为了炫富,也不是用来给你借的!谢谢理解!2.Fans不会轻易向别人借钱。金钱关系应该是双方甚至多方的合作关系。3.世人的烦恼很多都是因为金钱问题没有处理好而导致的。如果你摆平不了金钱,你很可能会被金钱......
  • 2012总结--第6篇--装备篇
    时代在进步,Fans的装备也再不断更新换代。1.天龙八部今年2月份的时候,又玩了下天龙八部-火影fans这个少林门派的号。终于下定决心,充值了300元,换成元宝后,从“元宝商店”买了10几个“3级宝石”。3级红宝石,3级皓石,3级碧玺,3级虎眼。打完宝石,看了下属性值,打了几个怪。和人PK下。尼......
  • 360看图 1.0.0.1010 精简优化版
    修改历史:2023.03.30:自改官方 1.0.0.1010最新正式版本2023.03.20:首个自改官方1.0.0.1002修改内容:基于官方最新版本制作,精简部分非必要文件;禁止软件自动更新;去除所有程序自校验,避免程序报错;其他细节调整下载链接: 自用资源,暂不公开!......
  • 大学毕业4年-回顾和总结(2)-钱,收入和支出
    过年回家,长辈最喜欢问两件事。第一件事,谈朋友没有啊。第二件事,现在一个月搞多少钱。   如果你和他们说,一个月工资是1万,那么他们立刻认为,你现在手上应该有十多万了。   上班族听了,心里咯噔一下。   收入多少和节余多少完全是两个概念,通常来说,收入决定了你节余的最高......