Android 过度渲染及优化方法--3D效果(JakeWharton大神的scalpel)

来源:互联网 发布:js currenttime 没用 编辑:程序博客网 时间:2024/03/29 17:18

1. 前言

Android 中的过度绘制是指同一个像素被绘制多次,从绘制性能角度讲,同一像素点被绘制的次数当然越少越好,这样有利于减轻 GPU 的工作压力,事实上,在具体开发过程中 ,不可避免的可能会出现过度绘制,这里,Android 系统本身在开发者选项里已经提供了一个选项开关 Debug GPU overdraw(调试 GPU 过度绘制),用于检测 App 的过度绘制, 只要打开这个开关,App 界面就会在不同的界面区域根据像素的绘制次数显示出不同的颜色。

2.基本介绍

1)打开手机的过度绘制开关。
操作顺序:【设置—>更多设置—>开发者模式—>调试GPU过度绘制—>显示过度绘制区域】

最后打开后如图所示:
这里写图片描述

2)颜色的标识

从好到差:蓝-绿-淡红-红,具体表现为:
1.蓝色1x过度绘制
2.绿色2x过度绘制
3.淡红色3x过度绘制
4.红色超过4x过度绘制

官方对过度渲染的图片介绍:
这里写图片描述

3)验收标准
1.控制过度绘制为2x
2.不允许存在4x过度绘制
3.不允许存在面积超过屏幕1/4区域的3x过度绘制(淡红色区域)

3.优化措施

由于公司项目不能拿来开放,自己写了个类似的登陆界面,如下所示:
这里写图片描述
可以看到,因为该界面布局简单,但是简单的界面也出现了红色,说明出现了过度渲染,下面我们就解决掉当前界面的过度渲染问题。

1)利用DDMS观察其他应用布局实现方式
这里写图片描述
具体使用方法前面已经介绍过:http://blog.csdn.net/dfskhgalshgkajghljgh/article/details/51331006
缺点:只能看清楚层次,不能知道具体什么原因导致过度渲染。

2)JakeWharton大神的scalpel
github连接:https://github.com/JakeWharton/scalpel
将当前页面的布局3D化,有点像xcode上的view ui hierarchy工具,效果如图所示:
这里写图片描述

优点:
1.可以很方便的在页面上看到布局的id,从而快速找出对应出问题的控件。
2.支持3D跟缩放功能,可以清晰看到布局文件的层次结构,跟引起过度渲染的层次或者对应的布局块,非常灵活。


使用步骤:
1.build.gralde中加入如下代码:

compile 'com.jakewharton.scalpel:scalpel:1.1.2'

2.使用的时候你的layout根节点必须是 ScalpelFrameLayout

@Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        View mainView = getLayoutInflater().inflate(R.layout.activity_main,null);        ScalpelFrameLayout scalpelFrameLayout = new ScalpelFrameLayout(this);        scalpelFrameLayout.addView(mainView);        scalpelFrameLayout.setLayerInteractionEnabled(true);        scalpelFrameLayout.setDrawIds(true);        setContentView(scalpelFrameLayout);        initView();        loadData();    }

3.其他方法

开启3D效果 : setLayerInteractionEnabled(boolean).显隐DrawViews:setDrawViews(boolean).显隐 view ID: setDrawIds(boolean).修改边框的颜色和阴影 setChromeColor(int) and setChromeShadowColor(int).

配置完成后,运行项目,当前页面则会呈现上图的效果。通过触摸页面,可以清楚的看到每个控件的id以及布局层次。从上图可以看到,过度渲染呈现出来的绿色,红色都是成块的,我这边LinearLayout没有定义id,如果定义id就更容易看出来,成块的都是LinearLayout布局,也就是背景颜色设置重复造成页面过度渲染。

4.查看xml文件

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:background="#ffffff"    android:orientation="vertical">    <ImageView        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:background="@mipmap/service_top_bg" />    <LinearLayout        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_marginTop="20dp"        android:background="#ffffff"        android:orientation="vertical">        <LinearLayout            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:background="#ffffff"            android:orientation="horizontal">            <TextView                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:layout_marginLeft="12dp"                android:text="用户名"                android:textSize="20sp" />            <EditText                android:id="@+id/user_name"                android:layout_width="match_parent"                android:layout_height="80dp"                android:layout_marginLeft="12dp"                android:background="@null"                android:hint="请输入用户名"                android:textSize="20sp" />        </LinearLayout>        <View            android:layout_width="match_parent"            android:layout_height="1dp"            android:background="#000000" />        <LinearLayout            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:orientation="horizontal">            <TextView                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:layout_marginLeft="12dp"                android:text="密码"                android:textSize="20sp" />            <EditText                android:id="@+id/password"                android:layout_width="match_parent"                android:layout_height="80dp"                android:layout_marginLeft="12dp"                android:background="@null"                android:hint="请输入密码"                android:textSize="20sp" />        </LinearLayout>        <View            android:layout_width="match_parent"            android:layout_height="1dp"            android:background="#000000" />        <Button            android:id="@+id/login"            android:layout_width="match_parent"            android:layout_height="50dp"            android:text="登录" />    </LinearLayout></LinearLayout>

第5,17,23都设置了背景颜色,而且都是LinearLayout,这样对于26行的textview来说,已经多了三层背景色,再加上自身内容的渲染,已经四层,肯定显示红色,也对应了3D模型显示的结果,我们的做法是去掉没有必要的背景颜色。更改后的xml文件如下所示:

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical">    <ImageView        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:background="@mipmap/service_top_bg" />    <LinearLayout        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_marginTop="20dp"        android:orientation="vertical">        <LinearLayout            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:orientation="horizontal">            <TextView                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:layout_marginLeft="12dp"                android:text="用户名"                android:textSize="20sp" />            <EditText                android:id="@+id/user_name"                android:layout_width="match_parent"                android:layout_height="80dp"                android:layout_marginLeft="12dp"                android:background="@null"                android:hint="请输入用户名"                android:textSize="20sp" />        </LinearLayout>        <View            android:layout_width="match_parent"            android:layout_height="1dp"            android:background="#000000" />        <LinearLayout            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:orientation="horizontal">            <TextView                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:layout_marginLeft="12dp"                android:text="密码"                android:textSize="20sp" />            <EditText                android:id="@+id/password"                android:layout_width="match_parent"                android:layout_height="80dp"                android:layout_marginLeft="12dp"                android:background="@null"                android:hint="请输入密码"                android:textSize="20sp" />        </LinearLayout>        <View            android:layout_width="match_parent"            android:layout_height="1dp"            android:background="#000000" />        <Button            android:id="@+id/login"            android:layout_width="match_parent"            android:layout_height="50dp"            android:text="登录" />    </LinearLayout></LinearLayout>

5.效果对比

优化前:
这里写图片描述

优化后:
这里写图片描述
这样页面已经没有了红色,都是蓝色,已经非常好了。可见,手机GPU过度绘制功能打开后再配合JakeWharton大神的Scalpel插件可以非常有效地定位过度绘制问题,完全可以代替SDK的Hierarchy UI功能,让开发者更好的优化布局层次。

4.优化总结

1.根布局的背景色谨慎设置,避免无效背景色。
2.减少布局层次,虽然布局层次不影响GPU过度渲染,但是复杂的嵌套势必会影响xml加载效率,也会增加像素点多次绘制的几率。

5.源码下载地址

源码下载地址:http://download.csdn.net/detail/dfskhgalshgkajghljgh/9719779


如有错误欢迎指出来,一起学习。

交流讨论群
群号:469890293

0 0
原创粉丝点击