软件加速,潜在的掉帧攻击者

问题的暴露与探索

使用universal图片库过程中发生了页面掉帧

1. 迁移的图片库的用法导致问题,根据uc侧图片库用法进行了对图片适配器做了修改。
2. 容器问题:
     2.1 单独使用原生RecyclerView的页面
     2.2 使用原生ImageView的页面
     2.3 使用原生RecyclerView、ImageView页面
     2.4 使用原生ListView的页面
     ...
 3. 内存问题,利用安卓调试工具查看内存,发现内存没有明显异常
 4. cpu问题,利用安卓调试工具查看,cpu也无明显繁忙
 5. 过度绘制
 6. TraceView最后才找到了硬件加速这个大boss

同一页面在不同情况下滑动中的屏幕刷新

在demoA(不同环境下)轻微滑动test3测试页面
软件加速,潜在的掉帧攻击者_第1张图片

在demoB中轻微滑动test3测试页面
软件加速,潜在的掉帧攻击者_第2张图片

对比图
软件加速,潜在的掉帧攻击者_第3张图片

发现在每隔16ms的屏幕刷新中,掉帧的场景中走了drawSoftware,而不是draw方法,下边是ViewRootImpl在屏幕刷新时的源码:
软件加速,潜在的掉帧攻击者_第4张图片

注释部分表示,如果硬件加速不可用情况下,会尝试用软件加速方式进行刷新。所以推断demoA页面应该没有开启硬件加速。在demoB中关闭默认的硬件加速,复现了demoA的掉帧。打开硬件加速后,demoA页面无异常。

硬件加速VS软件加速

硬件加速,直观上说就是依赖GPU实现图形绘制加速,同软硬件加速的区别主要是图形的绘制究竟是GPU来处理还是CPU,如果是GPU,就认为是硬件加速绘制,反之,软件绘制。在Android中也是如此,不过相对于普通的软件绘制,硬件加速还做了其他方面优化,不仅仅限定在绘制方面,绘制之前,在如何构建绘制区域上,硬件加速也做出了很大优化,因此硬件加速特性可以从下面两部分来分析:

1、前期策略:如何构建需要绘制的区域
2、后期绘制:单独渲染线程,依赖GPU进行绘制

无论是软件绘制还是硬件加速,绘制内存的分配都是类似的,都是需要请求SurfaceFlinger服务分配一块内存,只不过硬件加速有可能从FrameBuffer硬件缓冲区直接分配内存(SurfaceFlinger一直这么干的),两者的绘制都是在APP端,绘制完成之后同样需要通知SurfaceFlinger进行合成,在这个流程上没有任何区别,真正的区别在于在APP端如何完成UI数据绘制,

作者:看书的小蜗牛
链接:https://juejin.im/post/5a1f7b3e6fb9a0451b0451bb
来源:掘金

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

开启硬件加速

  1. 应用层
<application
         android:hardwareAccelerated="true">
application>
  1. Activity层
<activity
          android:hardwareAccelerated="true">
activity>
  1. Window层级
getWindow().setFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED, WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
  1. View层级
view.setLayerType(View.LAYER_TYPE_HARDWARE, null);

你可能感兴趣的:(Android)