前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android性能优化(六)之卡顿那些事

Android性能优化(六)之卡顿那些事

作者头像
用户2898788
发布2018-08-21 10:08:57
1.1K0
发布2018-08-21 10:08:57
举报

1、 Introduction

对普通用户而言,类如内存占用高、耗流量、耗电量等性能问题可能不会轻易发现,但是卡顿问题用户一定会立马直观的感受到。本文就带你一览卡顿的发生、检测、及优化。

2、 The Final Reason Why It Block ?

在《Android性能优化(二)之布局优化面面观》中我们说到:60fps VS 16ms。

60帧每秒是目前最合适的图像显示速度,也是绝大部分Android设备设置的调试频率,如果在16ms内顺利完成界面刷新操作可以展示出流畅的画面,而由于任何原因导致接收到VSYNC信号的时候无法完成本次刷新操作,就会产生掉帧的现象,刷新帧率自然也就跟着下降(假定刷新帧率由正常的60fps降到30fps,用户就会明显感知到卡顿)。

3、 The Ways Lead To Block

3.1 UI线程中的耗时操作
  • UI线程中有I/O读写、数据库访问等耗时操作;
3.2 复杂、不合理的布局以及OverDraw
  • 不合理的布局虽然可以完成功能,但随着控件数量越多、布局嵌套层次越深,展开布局花费的时间几乎是线性增长,性能也就越差;
  • 避免OverDraw导致的性能损耗;
  • 可以参考《Android性能优化(二)之布局优化面面观》
3.3 内存使用异常导致的卡顿
  • 内存抖动、内存泄漏都会导致:GC的次数越多、消耗在GC上的时间越长,CPU花在界面绘制上的时间相应越短;
  • 可以参考《Android性能优化(四)之内存优化实战》
3.4 错误的异步方式
  • 对线程开启方式的不同选择以及不同配置都可能导致卡顿的发生;
    • 在《Android性能优化(一)之启动加速35%》一文中说到过:不正确的异步任务不仅不能较好的完成异步任务,反而会加剧卡顿。关于异步任务开启的选择,之后会出一篇详细的文章,可以先参考启动加速的文章。

4、 The Ways To Find Block

4.1 StickMode

StrictMode类是Android 2.3 (API 9)引入的一个工具类,可以用来帮助开发者发现代码中的一些不规范的问题,以达到提升应用响应能力的目的。可以设置不同的线程检测策略、虚拟机检测策略。

 public void onCreate() {
     if (DEVELOPER_MODE) {
        // 线程检测策略
         StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
                 .detectDiskReads()
                 .detectDiskWrites()
                 .detectNetwork()   // or .detectAll() for all detectable problems
                 .penaltyLog()
                 .build());
        // 虚拟机检测策略    
         StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
                 .detectLeakedSqlLiteObjects()
                 .detectLeakedClosableObjects()
                 .penaltyLog()
                 .penaltyDeath()
                 .build());
     }
     super.onCreate();
 }

当违规操作发生时,可以根据自定义的策略记录下Log或者Crash,以便于跟踪改善。

4.2 TraceView

与StickMode相比,TraceView简直是发现Block根源的神器,不仅能看出每个方法消耗的时间、发生次数,并且可以进行排序,直接从最耗时的方法开始处优化;

关于TraceView的使用及分析,请参考《Android性能优化(一)之启动加速35%》第五章节。

4.3 AndroidPerformanceMonitor

AndroidPerformanceMonitor 是一个检测卡顿的开源库,前身是BlockCanary,更前身则是LeakCanary。而其使用与LeakCanary也比较相似,可以自主设置卡顿检测时间,检测到的卡顿同样是以Notification展示,在使用体验上也相当类似,与LeakCanary可以说是孪生兄弟。

原理 利用了Looper.loop()中每个Message被分发前后的Log打印,而我们设置自己的Printer就可以根据Log的不同的处理:

  • Message分发前,延时执行一个Runnable,这个时间可自己设置;
  • Message在规定的时间内完成分发,则会取消掉这个Runnable;
  • Message没有在规定的时间内完成分发,那这个Runnable就会被执行,可以获取到当前的堆栈信息;
// This must be in a local variable, in case a UI event sets the logger
Printer logging = me.mLogging;
if (logging != null) {
    logging.println(">>>>> Dispatching to " + msg.target + " " +
            msg.callback + ": " + msg.what);
}

msg.target.dispatchMessage(msg);

if (logging != null) {
    logging.println("<<<<< Finished to " + msg.target + " " + msg.callback);
}
4.4 ANR-WatchDog

ANR-WatchDog同样是一个检测卡顿的检测库,与AndroidPerformanceMonitor不一样的是它的原理相对简单:

  • 原理是开启一个线程,持续循环不断的往UI线程中Post一个Runnable(修改一个数的大小),然后在规定时间之后检测这个Runnable是否被执行(数的大小有没有 被修改过来)。没有被执行的话说明主线程执行上一个Message超时,然后获取当前堆栈信息;
  • ANR-WatchDog的原理更加简单,但是根据使用情况来看准确性不及AndroidPerformanceMonitor高,而且可设置的配置不如AndroidPerformanceMonitor丰富;
4.5 Choreographer

我们知道Android系统每隔16ms都会发出VSYNC信号,触发UI的绘制,而我们可以拿到回调的监听。如果16ms没有回调的话我们就知道发生了卡顿。

Choreographer.getInstance().postFrameCallback(new Choreographer.FrameCallback() {
            @Override
            public void doFrame(long l) {

            }
});

备注:这种方式的原理也比较简单,但是可用性不高,只能测出界面绘制的卡顿

5、 The Ways To Avoid Block

在第三节我们分析了产生卡顿的原因,那么避免卡顿的方法就很简单了:反其向行知即可。

5.1 将耗时操作移到异步中
  • 类如I/O读写、数据库访问等都应该采用异步的方式,不能有“只是一个很小的文件”之类的想法,防微杜渐;
5.2 合理优化布局,避免OverDraw。
  • 同样的实现功能界面,不同的布局方式产生的View个数以及渲染耗时差异是数倍的,恐怖的差异可以参考《Android性能优化(二)之布局优化面面观》;
5.3 合理优化内存
  • 节省内存的分配空间,尽可能的降低GC的频率,缩短GC的平均时间;CPU不被占用,卡顿的几率就会更低;
5.4 正确使用异步
  • 再次强调一遍:耗时操作不能都直接随意交给异步,不正确的异步使用方式反而会加剧卡顿;

6、 The Normal Ways Of Dealing Block

1. 开发中使用AndroidPerformanceMonitor检测卡顿进行处理; 2. 任何耗时操作正确的移到异步里; 3. 合理优化布局,避免OverDraw; 4. 优化内存分配,减少GC频率,这一般不是某个界面的事情,是一项长期工作;

7、 Block Check Of System

系统对Block有检测吗?那必须有!大名鼎鼎的ANR就来于此。

ANR的来龙去脉:触发场景、分析方法,你真的都清楚吗?欢迎关注下一篇文章,带你细究ANR不为人知的那些事。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2017-03-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 双十二技术哥 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1、 Introduction
  • 2、 The Final Reason Why It Block ?
  • 3、 The Ways Lead To Block
    • 3.1 UI线程中的耗时操作
      • 3.2 复杂、不合理的布局以及OverDraw
        • 3.3 内存使用异常导致的卡顿
          • 3.4 错误的异步方式
          • 4、 The Ways To Find Block
            • 4.1 StickMode
              • 4.2 TraceView
                • 4.3 AndroidPerformanceMonitor
                  • 4.4 ANR-WatchDog
                    • 4.5 Choreographer
                    • 5、 The Ways To Avoid Block
                      • 5.1 将耗时操作移到异步中
                        • 5.2 合理优化布局,避免OverDraw。
                          • 5.3 合理优化内存
                            • 5.4 正确使用异步
                            • 6、 The Normal Ways Of Dealing Block
                            • 7、 Block Check Of System
                            相关产品与服务
                            数据库
                            云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
                            领券
                            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档