解决Android 高CPU占用率的问题

 更新时间:2023年09月24日 09:29:06   作者:MinQ  
最近测试测试APP的一个功能,发现点击页面上的按钮后,CPU占有率比之前的版本要高,所以本文给大家介绍了如何解决Android 高CPU占用率的问题,需要的朋友可以参考下

背景

最近测试测试APP的一个功能,发现点击页面上的按钮后,CPU占有率比之前的版本要高,达到了4%,之前的版本只有不到1%。由于两个版本之间代码提交特别多,无法直接通过代码变动来对比分析。只好直接通过AS工具profiler来分析应用CPU占用了,看下如何优化。

分析过程

首先从测试同学口中知道了CPU占用出现异常的场景是点击页面上的功能A的按钮。OK,那我们就从点击这个按钮入手。首先打开Profiler,选择对应的APP进程,开始监听当前进程的CPU占用率。

双击CPU一行,我们进入到CPU详情页面,如下:

可以看到在左侧,有4个选项,且下方有record按钮。这里的含义是,我们通过点击record后,profile会开始记录接下来一段时间内,详细的CPU占用信息,记录哪些信息呢,通过上述四个选项供我们选择。

  • Callstack Sample

会显示当前这段时间内,涉及到的进程以及调用栈都有哪些,会精细到进程和具体代码。

  • System Trace

会显示详细的信息,包括VSYNC UI绘制信号,内存占用(不是详细内存占用),各个线程的运行时间和CPU占用。也会精确到代码,但是不会特别详细。适合分析record中等时长的数据。此外这里包含的信息会很多,有助于先手分析。

  • Java/Kotlin Method Trace

内容更详细,会精细到各行代码,但是这个不适合record抓取太长时间的文件,因为AS分析会占用很长时间。

我们先选择SystemTrace,点击Record开始记录信息,我们接着点击功能A按钮,开始复现问题场景,问题复现,点击Stop按钮停止抓取,接着AS会自动解析文件,生成我们详细信息,如下图:

可以看到UI的刷新VSYNC信号刷新很频繁,对应下方主线程代码,存在不少峰值。我们放大下方代码峰值,找到最下方峰顶代码,

可以看到下方在layout中,不停的obtainview,这里有可能是一个列表,ListView或者rectclerview,在不停的更新数据。

我们接着抓一份Java Kotlin Method Trace分析看下:

注意这里要点开:

然后我们随意找到一个峰值,查看其代码源:

这里可以直接直观的看到定位到了我们的代码,LogViewer控件,我们点进去查看源码,会发现里边定义了一个listView。这个ListView的功能是在APP上显示logcat日志,当点击功能A按钮时,会产生大量日志,然后每次需要打印一行日志时候,就会全部更新listView的所有控件,(代码内容不方便粘贴)所以造成APP UI绘制高频率进行,导致CPU的占用率居高。

定位到问题了:ListView不停的刷新UI,导致VSYNC不停的触发绘制,导致CPU占用率高

解决问题

现在我们定位到了问题所在,那么怎么解决呢?

第一步,极端化,直接去掉对应UI

首先我们最直接的方法就是把这个UI直接屏蔽掉,不去初始化以及展示这个UI。

这种处理下,我们看下数据,如图,很明显,VSYNC触发周期长了,UI绘制频率下来了,交给测试一看,CPU占用率降到了1.1%, 直接降了3%。

但是直接去掉这个UI,其实不是很妥,毕竟这样相当于这个UI需求给废了。 我们从ListView代码入手,ListView会产生很多个子View,在我们这个需求中,需要显示logcat日志,意味着,每一行日志都会新生成一个view放入到logcat中,日志越打越多,view对象也越多。不仅UI绘制频繁,内存也会持续上升。所以这里想优化只能减少view的个数,但是,日志内容不能少,个数怎么减呢?比如把所有内容做一个整体,作为一个字符串显示到控件中,但这样就不需要listView了,直接一个TextView即可。我们试下这种方案。

第二步,尝试TextView替换listview实现需求

将布局替换为TextView,通过textView的append属性来实现追加日志内容。可以看到效果出奇的好,VSYNC信号不会很频繁,且没有生成多余的对象。

性能狗测试了一下,CPU占用率为1.7%。

但是TextView也有弊端,对于数据的操作没有listView和recyclerview那么精细化,如果因为业务需求,仍然想用listview怎么办呢?

第三步,尝试优化listView

实际需求中,如果我们绕不开listView,那么就只能想办法去优化它了。从之前的数据来看,是因为UI刷新太频繁,那么我们降低UI的刷新频率呢? 这里改动了一下代码:缓存日志信息,每过500ms才去刷新UI,将缓存的日志显示到listView中,这样改完后,看下效果:

有一些好转,使用性能狗测试下,看看,结果CPU占用率为2.4%,也优化了不少。

总结

对于这种问题,利用好工具profiler对程序进行分析。能够快速找到问题原因的基础在于对工具的熟练程度,对于AS工具的使用,可以直接参考官方文档的介绍:https://developer.android.google.cn/studio/profile/power-profiler?hl=zh-cn

以上就是解决Android 高CPU占用率的问题的详细内容,更多关于Android高CPU占用率的资料请关注脚本之家其它相关文章!

相关文章

  • Android ViewPager无限循环实现底部小圆点动态滑动

    Android ViewPager无限循环实现底部小圆点动态滑动

    这篇文章主要为大家详细介绍了Android ViewPager无限循环实现底部小圆点动态滑动的相关资料,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-03-03
  • 详解Android .9.png “点九”图片的使用

    详解Android .9.png “点九”图片的使用

    这篇文章主要为大家详细介绍了Android .9.png “点九”图片的使用方法,感兴趣的小伙伴们可以参考一下
    2016-09-09
  • Android实现可拖动层叠卡片布局

    Android实现可拖动层叠卡片布局

    这篇文章主要为大家详细介绍了Android实现可拖动层叠卡片布局,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-11-11
  • 从"Show tabs"了解Android Input系统

    从"Show tabs"了解Android Input系统

    这篇文章主要介绍了从"Show tabs"了解Android Input系统的相关资料,需要的朋友可以参考下
    2023-01-01
  • Android开发之自定义刮刮卡实现代码

    Android开发之自定义刮刮卡实现代码

    本篇文章主要介绍了Android开发之自定义刮刮卡实现代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-07-07
  • 详解Android原生json和fastjson的简单使用

    详解Android原生json和fastjson的简单使用

    本文主要介绍了Android原生json和fastjson的简单使用,具有一定的参考价值,下面跟着小编一起来看下吧
    2017-01-01
  • android调用web service(cxf)实例应用详解

    android调用web service(cxf)实例应用详解

    Google为ndroid平台开发Web Service提供了支持,提供了Ksoap2-android相关架包接下来介绍android调用web service(cxf),感兴趣的朋友可以了解下
    2013-01-01
  • Android自定义控件实现圆形进度条

    Android自定义控件实现圆形进度条

    这篇文章主要为大家详细介绍了Android自定义控件实现圆形进度条的相关资料,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-01-01
  • android ListView深入理解

    android ListView深入理解

    在android开发中ListView是比较常用的组件,它以列表的形式展示具体内容,并且能够根据数据的长度自适应显示。抽空把对ListView的使用做了整理,需要的朋友可以参考下
    2012-11-11
  • Android使用线程更换壁纸

    Android使用线程更换壁纸

    这篇文章主要为大家详细介绍了Android使用线程更换壁纸的方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-11-11

最新评论