卡顿现象对我们来说是一个很烦恼的问题,也会给用户使用过程中带来很直观的不良感受,主要是由代码、内存不足等问题引起的常规卡顿和ANR异常,我们可以使用“友盟+u-apm”这款工具进行监测,利用线上和线下相结合的方式全覆盖监测卡顿点,寻找出导致app的原因,以下文章就介绍卡顿的原因,针对这些原因提出解决方案并进行修复!

1.过于复杂的布局

原因:UI布局层次太深, 或是自定义控件的onDraw中有复杂运算, CPU的相关运算就可能大于16ms, 导致卡顿。

解决方案:可通过Android Studio的Layout Inspector去查看层级,并改善层级深度,在开发中建议使用ConstrainLayout改善减少层级。

2.过度绘制

原因:像素被多次绘制。

解决方案:可在开发者模式中,打开显示边界布局,查看绘制颜色。

1.原色 – 没有被过度绘制 – 这部分的像素点只在屏幕上没有绘制。

2.蓝色 – 1次过度绘制– 这部分的像素点只在屏幕上绘制了一次。

3.绿色 – 2次过度绘制 – 这部分的像素点只在屏幕上绘制了二次。

4.粉色 – 3次过度绘制 – 这部分的像素点只在屏幕上绘制了三次。

5.红色 – 4次过度绘制 – 这部分的像素点只在屏幕上绘制了四次及以上。

2.1clipRect、clipRect

使用canvas.clipRect后,绘制区域之外的绘制指令都不会被执行,那些部分内容在矩形区域内的组件,仍然会得到绘制。

canvas.quickreject()来判断是否没和某个矩形相交,从而跳过那些非矩形区域内的绘制操作。

3. 耗时事件

原因:在UI线程中执行耗时事件,会导致UI线程loop卡顿。

解决方案:如果UI线程发生卡顿,即dispatchMessage发生了卡顿。我们可在dispatchMessage的原理分发消息前和分发消息后时间间隔与我们设置的阈值对比。

4. 频繁GC

原因:短时间内创建大量对象进入新生区,导致频繁的GC。gc会大量占用ui线程和cpu资源,会导致app整体卡顿。

解决方案:使用Profiler查看CPU抖动位置,跟踪内存分配情况找到对象重复创建的对象。

5. 内存不足

原因:低内存会导致磁盘 IO 变多, 如果频繁进行磁盘 IO , 由于磁盘IO 很慢, 那么主线程会有很多进程处于等 IO 的状态。

解决方案:使用 SharedPerforence 时用 Apply而不是commit等等。

帧率与刷新率不匹配

原因:屏幕帧率和系统的 fps 不相符 , 那么有可能会导致画面不是那么顺畅. 比如使用 90 Hz 的屏幕搭配 60 fps 的动画

解决方案:使用以下代码获取屏幕刷新率,根据屏幕刷新率进行动画计算。

除以上问题外,造成卡顿的原因还有GPU频繁渲染、频繁调用 buildDrawingCache、使用CPU渲染而不是使用GPU、WebView 性能不足等等问题都会造成卡顿。分析app卡顿的原因可以借助“友盟+u-apm应用性能监控平台”作为小助手,它作为一款监测工具不仅可以帮助开发者监测app性能方面的问题,还可以实时监测定位到app卡顿的问题所在处,从而根据问题去进行修复并解决。

另外,友盟通过轻量级的集成接入即可拥有实时、可靠、全面的应用崩溃、ANR、自定义异常等捕获能力,及卡顿、启动分析等性能能力,还提供了云真机测试能力,助力开发者从研发测试质量验收到线上问题复现排查,保障应用品质,提升测试效率。在云真机测试期间自动采集崩溃信息,提供详尽的崩溃报告协助筛查,真正实现监控测试全流程深度打通。它的功能不单单只有这些,还有多种功能供开发者使用,既可以在工作上帮助到开发者,又能减轻负担和压力~