GPU|如何用 GPU硬件层加速优化Android系统的游戏流畅度( 三 )


(2)需要将硬件层更新可视化:
使用开发人员选项 , 可以启用“显示硬件层更新” 。 如果在应用硬件层后更改视图 , 它将使硬件层无效并将视图重新渲染到该屏幕外缓冲区 。
硬件加速优化 但是由此带来了一个问题是 , 在不需要快速渲染的界面 , 比如滚动栏 硬件层也会更快地渲染它们 。 当将 ViewPager 滚动到两侧时 , 它的页面在整个滚动阶段会以绿色突出显示 。
因此当我滚动 ViewPager 时 , 我使用 DDMS 运行 TraceView , 按名称对方法调用进行排序 , 搜索“android/view/View.setLayerType” , 然后跟踪它的引用:
ViewPager#enableLayers(): private void enableLayers(boolean enable) { final int childCount = getChildCount(); for (int i = 0; ichildCount; i++) { final int layerType = enable ? ViewCompat.LAYER_TYPE_HARDWARE : ViewCompat.LAYER_TYPE_NONE; ViewCompat.setLayerType(getChildAt(i) layerType null);
该方法负责为 ViewPager 的孩子启用/禁用硬件层 。 它从 ViewPaper#setScrollState() 调用一次:
private void setScrollState(int newState) { if (mScrollState == newState) { return;mScrollState = newState; if (mPageTransformer != null) { enableLayers(newState != SCROLL_STATE_IDLE);if (mOnPageChangeListener != null) { mOnPageChangeListener.onPageScrollStateChanged(newState);
正如代码中所示 , 当滚动状态为 IDLE 时硬件被禁用 , 否则在 DRAGGING 或 SETTLING 时启用 。 PageTransformer 旨在“使用动画属性将自定义转换应用于页面视图”(Source) 。
基于我们的需求 , 只在渲染动画的时候启用硬件层 , 所以我想覆盖ViewPager 方法 , 但由于它们是私有的 , 我们无法修改这个方法 。
所以我采取了另外的解决方案:在 ViewPage#setScrollState() 上 , 在调用enableLayers() 之后 , 我们还会调用OnPageChangeListener#onPageScrollStateChanged() 。 所以我设置了一个监听器 , 当 ViewPager 的滚动状态不同于 IDLE 时 , 它将所有 ViewPager 的孩子的图层类型重置为 NONE:
@Override public void onPageScrollStateChanged(int scrollState) { // A small hack to remove the HW layer that the viewpager add to each page when scrolling. if (scrollState != ViewPager.SCROLL_STATE_IDLE) { final int childCount =your_viewpager.getChildCount(); for (int i = 0; ichildCount; i++)your_viewpager.getChildAt(i).setLayerType(View.LAYER_TYPE_NONE null);
这样 , 在 ViewPager#setScrollState() 为页面设置了一个硬件层之后——我将它们重新设置为 NONE , 这将禁用硬件层 , 因此而导致的帧率区别主要显示在 Nexus上 。
作者:陈可心
本文为阿里云原创内容 , 未经允许不得转载 。