练习:https://github.com/zhangbz/AndroidUIPorblems
查看过度绘制
在开发者选项中开启"调试GPU过度绘制"
判断标准
无色:没有过度绘制,即只绘制了一次
蓝色:一倍过度绘制
绿色:二倍过度绘制
淡红色:三倍过度绘制
红色:四倍或以上过度绘制
实践
其中"This is test"四次或以上倍数过度绘制,其背景三倍,按钮两倍,按钮中的文字三倍,背景一倍.
Mainactivity优化
首先分析布局文件,发现嵌套的LinearLayout设置了与父LinearLaytout相同的背景色,故删除其背景色设置,效果如下
然后由于Android自带的一些主题,window会被默认添加一个纯色的背景,因为这个Activity的界面的背景占满了整个屏幕,所以我们可以去掉该activity的默认绘制,在mainactivity的onCreate()方法里面修改代码。
1 2 3 4 5 6 7 8 | protected void onCreate(Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_main); getWindow().setBackgroundDrawable( null ); //新增代码 //... } |
效果如下:
至此,消除了该页面三倍及以上过度绘制.
overdrawview优化
原实现方法如下,由于onDraw()方法中绘制的图形存在覆盖现象,因而导致了过度绘制
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | @Override protected void onDraw(Canvas canvas) { super .onDraw(canvas); int width = getWidth(); int height = getHeight(); mPaint.setColor(Color.GRAY); canvas.drawRect( 0 , 0 , width, height, mPaint); mPaint.setColor(Color.CYAN); canvas.drawRect( 0 , height/ 4 , width, height, mPaint); mPaint.setColor(Color.DKGRAY); canvas.drawRect( 0 , height/ 3 , width, height, mPaint); mPaint.setColor(Color.LTGRAY); canvas.drawRect( 0 , height/ 2 , width, height, mPaint); } |
修改代码,避免相互覆盖
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | @Override protected void onDraw(Canvas canvas) { super .onDraw(canvas); int width = getWidth(); int height = getHeight(); mPaint.setColor(Color.GRAY); canvas.drawRect( 0 , 0 , width, height/ 4 , mPaint); mPaint.setColor(Color.CYAN); canvas.drawRect( 0 , height/ 4 , width, height/ 3 , mPaint); mPaint.setColor(Color.DKGRAY); canvas.drawRect( 0 , height/ 3 , width, height/ 2 , mPaint); mPaint.setColor(Color.LTGRAY); canvas.drawRect( 0 , height/ 2 , width, height, mPaint); } |
优化效果
busyondraw优化
点击按钮时会出现明显的卡顿现象,从以下代码中可以判断,造成该问题的原因应该是onDraw()方法中的耗时操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | @Override protected void onDraw(Canvas canvas) { super .onDraw(canvas); for ( int i = 0 ; i < 1000 ; i++) { System.out.println( "canvas = [" + canvas + "]" + i); } Paint paint = new Paint(); paint.setColor(Color.RED); paint.setStyle(Paint.Style.STROKE); paint.setStrokeWidth( 4 ); int radius = Math.min(getWidth(), getHeight()) / 2 ; canvas.drawCircle(getWidth()/ 2 , getHeight()/ 2 , radius, paint); } |
优化方案:将耗时操作移入到子线程中
1 2 3 4 5 6 7 8 | new Thread( new Runnable() { @Override public void run() { for ( int i = 0 ; i < 1000 ; i++) { System.out.println( "canvas = [" + canvas + "]" + i); } } }).start(); |
#学习笔记,如有谬误,敬请指正。#
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步