美文网首页android跟着产品学技术自定义views
Android App卡顿分析,以及使用Choreographe

Android App卡顿分析,以及使用Choreographe

作者: 梦飞成2012 | 来源:发表于2016-12-20 20:08 被阅读4206次

    1、背景:

    卡顿是最影响App用户体验的原因之一。卡顿造成的原因多种多样,简单列举一下

    1、布局层级过多,设置无用的背景色,布局中添加了多种不必要的背景色,导致view绘制的时候多次绘制,引起卡顿
    2、布局太复杂,嵌套过多,例如RelativeLayout 相比LinearLayout,可以有效减少布局层级,层级太复杂,会影响view的measure时间,进而造成卡顿。
    3、内存使用不当,主线程做了大量计算或者IO操作等,这样就不举例说明了。
    

    2、性能问题常用检测方法

    检测app绘制性能的方法多种多样:

    如针对对于布局层级过多,可以使用开发者选项-->调用GPU过度绘制 方式查看。
    
    针对布局复杂,可以用Hierarchy Viewer
    
    也可以使用腾讯提供的性能检测工具:GT(GitHub地址:https://github.com/FanGuangcheng/GT)
    

    然而,这所有的检测方法都是开发阶段进行的,当我们的app投放到市场之后,我们不知道用户那边使用的真实场景是怎样的。

    我们开发、测试进行的性能检测,都是针对我们的开发机器,没法真实模拟用户场景,比如用户多种多样的机型、内存大小、app使用状态、SD卡使用状态等等。
    因此我们需要一种线上的监测机制,实时统计用户的卡顿数据,获得用户使用的第一手资料,并有针对性的对某些功能页面进行优化,更好的提升用户体验。



    3、android绘制原理

    ** Android 16ms原理**:Android系统每隔16ms会发出VSYNC信号重绘我们的界面(Activity).为什么是16ms, 因为Android设定的刷新率是60FPS(Frame Per Second), 也就是每秒60帧的刷新率, 约合16ms刷新一次.
    如下图所示:


    16ms

    如图中所示,每隔16ms,系统都会发出VSYNC信号,如果这时候我们的画面(view)准备好了,我们的view绘制就会很流畅。如果我们在这个16ms间隔内,没有准备好画面(view),那么这一次绘制,就不会展示在屏幕上,就相当于少绘制了一帧,画面就会出现卡顿,断断续续。 如下图所示

    卡顿的原因

    4、Choreographer 监测掉帧原理

    在Choreographer中有个回调接口,FrameCallback。

    public interface FrameCallback { public void doFrame(long frameTimeNanos); }
    doFrame 的注释如下:* Called when a new display frame is being rendered.
    就是说,当新的一帧被绘制的时候被调用。
    因此我们利用这个特性,可以统计两帧绘制的时间间隔。
    主要流程如下:

    • 1、实现Choreographer.FrameCallback接口,比如实现类是FrameSkipMonitor

    • 2、在doFrame中统计两帧绘制的时间,代码与注释如下:
      @Override
      public void doFrame(long frameTimeNanos) {
      if (mLastFrameNanoTime != 0) {//mLastFrameNanoTime 上一次绘制的时间
      long frameInterval = frameTimeNanos - mLastFrameNanoTime;//计算两帧的时间间隔
      //如果时间间隔大于最小时间间隔,316ms,小于最大的时间间隔,6016ms,就认为是掉帧,累加统计该时间
      //此处解释一下原因: 因为正常情况下,两帧的间隔都是在16ms以内 ,如果我们统计到的两帧间隔时间大于三倍的普通绘制时间,我们就认为是出现了卡顿,之所以设置最大时间间隔,是为了有时候页面不刷新绘制的时候,不做统计处理
      if (frameInterval > MIN_FRAME_TIME && frameInterval < MAX_FRAME_TIME) {
      long time = 0;
      if (mSkipRecordMap.containsKey(mActivityName)) {
      time = mSkipRecordMap.get(mActivityName);
      }
      mSkipRecordMap.put(mActivityName, time + frameInterval);//统计时间
      }
      }
      mLastFrameNanoTime = frameTimeNanos;
      Choreographer.getInstance().postFrameCallback(this);
      Runtime.getRuntime().maxMemory();
      }

    • 3、启动监测
      public void start() {
      Choreographer.getInstance().postFrameCallback(FrameSkipMonitor.getInstance());
      }

    • 4、上报处理
      在doFrame选中,我们已经统计到了想要的数据,然后我们将time的值除以16600000(因为我们统计的时间是纳秒),就是掉帧的数字。

    demo源码地址:https://github.com/FanGuangcheng/FrameSkipMonitor(github代码由于涉及公司部分源码已删除)
    新链接地址,大家感兴趣可以下载demo看看:
    链接: https://pan.baidu.com/s/1hrG2sDY 密码: u9gp
    源码简要解读:
    最重要的两个类
    FrameSkipMonitor:统计绘制间隔的时间处理操作。
    MyActivityLifeCycle:activity相关的跳转纪录操作,通过纪录,就可以统计每个页面的掉帧卡顿时间。



    参考资料:

    1、http://www.jianshu.com/p/1fb065c806e6
    2 、https://mp.weixin.qq.com/s?__biz=MzAxMzYyNDkyNA==&mid=2651332439&idx=1&sn=ba542ffeb494d827b9009d4e2128ed5c&scene=1&srcid=0818mFLqkkIMoS7vzjxTOEq2&key=8dcebf9e179c9f3a440c75502cc03ba23f09db161f5a3a4bd15acbdaa6b2ac0e641552d3b40a09b753739924009c9bfb&ascene=0&uin=Mjc3OTU3Nzk1&devicetype=iMac+MacBookPro10%2C1+OSX+OSX+10.10.5+build%2814F1909%29&version=11020201&pass_ticket=jzkG1H7kXvY27npmMnFUaa1eMShQT4c0PYd9r8wDanabk59MHU0ynkDd6oxen8jH

    相关文章

      网友评论

      • mee_fbda:学习了,但是还是没明白为什么把两次回调超过三倍的回调时间作为掉帧的标准,正常情况下是不是超过两倍的话就已经是jank了吗,可是改了代码里的MIN_FRAME_TIME为两倍回调时间时掉帧数会很大,觉得也不对,所以请教下楼主的这个三倍回调时间的具体原理,多谢了
      • 小红军storm:你这个到底统计了什么
        梦飞成2012:@小红军storm 这个没办法定位,只是知道那个页面有卡顿的情况,目前市面上还没有三方库可以检测到卡顿的源码的,leakCanary和BlockCanary ,一个可以检测内存未释放问题,一个key检测卡顿发生,可以参考下
        小红军storm:@梦飞成2012 那怎么定位是页面中的那段代码造成的卡顿呢
        梦飞成2012:@小红军storm 如果两次回调的时间,超过了阀值,那么就认为这一帧数据没有显示出来,就上报给后台,然后我们就可以统计某个页面,上报的次数,次数越多,某个页面的卡顿情况越严重
      • 恩爱之林先生:辛苦了
        梦飞成2012:@violet小咔咔 不好意思,demo示例里面涉及了部分公司的代码,不得不删除,防止代码泄漏,过几天,我上次到百度云,再给大家一个链接吧
        violet小咔咔:@梦飞成2012 demo怎么是404,老铁,还有一个问题,你的activityName是什么时机赋值的
        梦飞成2012:哈哈,为人民服务

      本文标题:Android App卡顿分析,以及使用Choreographe

      本文链接:https://www.haomeiwen.com/subject/zdkfvttx.html