日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android 高级进阶之overdraw分析及解决

發布時間:2025/7/14 Android 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android 高级进阶之overdraw分析及解决 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

最近在看Android中性能優化的,其中提到了LinearLayout會引起overdraw,但是并沒有具體的分析原因,我自己查找了一些資料從LinearLayout的繪制等方面來說明為什么使用LinearLayout會引起overdraw和哪些情況下使用LinearLayout會引起overdraw。希望大家看完之后對view的繪制和測量過程更加了解。

什么是overdraw

Android中在屏幕上繪制一個像素會花一定的時間,如果在屏幕的同一個位置多次繪制就會花大量的時間,多次在屏幕上同一位置繪制的情況就成為overdraw。overdraw會非常影響應用的性能。一個高效的布局要做到兩點: 1、減少overdraw。

2、簡化布局結構。

看下一個overdraw的例子

上面的六張牌的重合部分被多次繪制引發了overdraw,

檢測overdraw

可以通過手機的設置來直觀的查看應用的overdraw情況。 1、打開設置,打開開發者選項。 2、選擇調試GPU過度渲染。 3、打開顯示過度渲染區域。

上面左邊是正常的未打開,調試GPU過度渲染的情形,右邊是打開GPU過度渲染檢測之后的。 上面右圖中不同的顏色對應不同的overdraw的次數。對應關系如下:

如下三幅圖,最右邊的是基本上沒有overdraw或者只有一次overdraw的,而中間的紅色區域很多,大部分是有三次及以上的overdraw。overdraw的次數越多越影響性能,所以中間的這種是不提倡的。

減少overdraw的方法

1、減少不必要的background

因為有background的時候會先繪制一遍background然后再在background的基礎上面繪制其他元素,所以會增加一次overdraw。 所有用戶看不到的background都應該刪除掉。 如下面的這個例子:

刪除background之前

<ImageViewandroid:layout_width="match_parent"android:layout_height="match_parent"android:src="@drawable/beach"android:background="@android:color/white"> </ImageView> 復制代碼

刪除background之后

<ImageViewandroid:layout_width="match_parent"android:layout_height="match_parent"android:src="@drawable/beach" > </ImageView> 復制代碼

因為imageView的background在有src的時候根本就不會被用戶觀察到,所以應該刪除掉。

2、統一整個app的background顏色

可以通過設置整個app的統一背景色來防止不同的activity設置不同的背景色而導致多個background。可以在AndroidManifest.xml添加:

android:theme="@android:style/Theme.Light" 復制代碼

或者想要的背景色。

2、使用clip減少渲染區域

clip具有裁剪功能,在自定義view的時候,渲染的圖像可能和用戶觀察到的圖像不一樣,自定義view的ondraw方法里面不僅僅只渲染用戶可見的圖像而且會渲染到被遮擋的圖像,使用clip方法裁剪出用戶可見的區域,這樣可以減少overdraw。

使用clipRect()方法

在自定義view中使用 Canvas.clipRect()方法可以有效的減少overdraw。這個方法可以為自定義的view提供一個rectangle 區域,并且只有在這個區域中的內容才會被繪制。上面的撲克牌就可以使用Canvas.clipRect()來減少繪制。如下:

下面通過一個自定義的view來進行一個對比:

未使用clipRect()的自定義view

/*** Created time 20:54.** @author huhanjun* @since 2019/6/12*/ public class MyView extends View {private Paint mPaint;private Bitmap mBitmap;private int mPadding = 0;public MyView(Context context) {super(context);}public MyView(Context context, @Nullable AttributeSet attrs) {super(context, attrs);mPaint = new Paint();mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.over_draw);}public MyView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);mPaint = new Paint();mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.over_draw);}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);for (int i = 0; i < 5; i++) {canvas.save();canvas.drawBitmap(mBitmap,mPadding,0,mPaint);canvas.restore();mPadding += 200;}} } 復制代碼

在開啟檢測overdraw后的顯示效果如下:

上圖從左到右可以由顏色看出分別進行了一次,兩次,三次和多次的overdraw,下面看看使用clipRect()后的顯示效果。

使用clipRect()的自定義view

/*** Created time 20:54.** @author huhanjun* @since 2019/6/12*/ public class MyView extends View {private Paint mPaint;private Bitmap mBitmap;private int mPadding = 0;public MyView(Context context) {super(context);}public MyView(Context context, @Nullable AttributeSet attrs) {super(context, attrs);mPaint = new Paint();mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.over_draw);}public MyView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);mPaint = new Paint();mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.over_draw);}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);for (int i = 0; i < 5; i++) {canvas.save();Rect rect = new Rect(mPadding, 0, 200+mPadding, mBitmap.getWidth() + mPadding);canvas.clipRect(rect);//此處增加clipRect方法canvas.drawBitmap(mBitmap,mPadding,0,mPaint);canvas.restore();mPadding += 200;}} } 復制代碼

運行后的顯示效果如下:

可以看出從左到右所有的圖片都只進行了一次overdraw。大大減少了渲染次數。 Canvas.clipRect()該方法用于裁剪畫布,也就是設置畫布的顯示區域 調用clipRect()方法后,只會顯示被裁剪的區域,之外的區域將不會顯示 .

3、盡量少用透明(alpha )效果

Alpha是圖形界面開發中常用的特效,通常我們會使用以下代碼來實現Alpha特效:

view.setAlpha(0.5f);View.ALPHA.set(view, 0.5f);ObjectAnimator.ofFloat(view, "alpha", 0.5f).start();view.animate().alpha(0.5f).start();view.setAnimation(new AlphaAnimation(1.0f, 0.5f)); 復制代碼

其效果都等同于:

canvas.saveLayer(l, r, t, b, 127, Canvas.CLIP_TO_LAYER_SAVE_FLAG); 復制代碼

渲染帶有透明度像素被稱為:alpha rendering,alpha rendering會導致overdraw,因為系統會先渲染透明像素,然后渲染透明像素下面的view的像素,最后結合兩者,從而產生透明度的效果,因此會導致overdraw。如下圖:

上圖左邊是沒有加透明度的像素,右邊是在其上面加上一個透明度的蒙層,下面的圖是加上透明度后最終產生的效果。 類似于透明動畫,淡入,淡出等或者帶有陰影的效果都會導致alpha rendering。因此會導致overdraw。下面看一個由于設置alpha引起性能問題的實例。

Android Performance Case

在開發者模式中打開GPU profiling 工具后,發現上圖中右邊存在明顯的掉幀現象(底下紅柱超過藍線部分的),打開Tracer for OpenGL工具來檢測后發現: 是由viewpager上面滑動時標志當前位置和其他位置的白色小點引起的,這些白色的小點,設置了透明度,每次都會調用Canvas.saveLayer()生成一個臨時圖層。正好滿足了以下條件:

getAlpha() returns a value < 1 onSetAlpha() returns false getLayerType() returns LAYER_TYPE_NONE hasOverlappingRendering() returns true 復制代碼

上面的用紅色區域標記出來的圓點,在每次滑動viewpager的時候都會動態調用setAlpha()方法來改變顏色和透明度,因此引起了overdraw和掉幀。為了解決上面的問題,可以采用下面的任一種方法:

1、Use a customizable “inactive” color instead of setting an opacity on the View

2、 Return false from hasOverlappingRendering() and the framework will set the proper alpha on the Paint for you

(注意:在android的View里有透明度的屬性,當設置透明度setAlpha的時候,android里默認會把當前view繪制到offscreen buffer中,然后再顯示出來。 這個offscreen buffer 可以理解為一個臨時緩沖區,把當前View放進來并做透明度的轉化,然后在顯示到屏幕上。這個過程是消耗資源的,所以應該盡量避免這個過程。而當繼承了hasOverlappingRendering()方法返回false后,android會自動進行合理的優化,避免使用offscreen buffer。 )

3、Return true from onSetAlpha() and set an alpha on the Paint used to draw the “gray” circles

如何高效的使用alpha屬性

上面已經說到了使用alpha屬性的時候會導致overdraw,那么應該如何避免這些情況以減少overdraw呢? 下面分別對textview,imageview,和customview中使用到alpha情況進行說明:

textview 對于TextView我們通常需要文字透明效果,而不是View本身透明,所以,直接設置帶有alpha值的TextColor是比較高效的方式。

// 錯誤使用方式textView.setAlpha(alpha);//---------------------------------------------------------------- //正確方式 // 以下方式可以避免創建 offscreen bufferint newTextColor = (int) (0xFF * alpha) << 24 | baseTextColor & 0xFFFFFF;textView.setTextColor(newTextColor); 復制代碼

ImageView 同樣的對于只具有src image的ImageView,直接調用setImageAlpha()方法更為合理。

//1、 錯誤方式, setAlpha方法由View繼承而來,性能不佳imageView.setAlpha(0.5f); //------------------------------------------------------------- //正確方式 // 使用以下方式時,ImageView會在繪制圖片時單獨為圖片指定Alpha// 可以避免創建 offScreenBufferimageView.setImageAlpha((int) alpha * 255); 復制代碼

CustomView 類似的,自定義控件時,應該直接去設置paint的alpha。

//錯誤方式customView.setAlpha(alpha); //---------------------------------------------------- // 正確方式 But thispaint.setAlpha((int) alpha * 255);canvas.draw*(..., paint); 復制代碼

LinearLayout導致的overdraw

未完待續

參考文獻

1、google-developer-training.github.io/android-dev… 2、sriramramani.wordpress.com/2015/05/06/… 3、helw.net/2016/01/27/… 4、www.cnblogs.com/tianzhijiex… 5、www.androidperformance.com/2015/03/31/… 6、www.curious-creature.com/2015/03/25/… 7、www.curious-creature.com/2012/12/01/… 8、yangm90.github.io/android-Alp…

轉載于:https://juejin.im/post/5d01b4b45188251ed0326930

總結

以上是生活随笔為你收集整理的Android 高级进阶之overdraw分析及解决的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 亚洲男人第一av | 一区二区三区四区国产 | 日本一区二区色 | a在线观看免费 | 中文字幕一区二区三区精华液 | 黄色午夜| 伊人精品视频在线观看 | 国产精品热久久 | 男男成人高潮片免费网站 | 日本一级黄色大片 | 久久久精品视频在线观看 | 国产一区二区网 | 91精品国产91久久久 | 国产激情视频一区二区 | 极品少妇av | 一级片久久 | 久久国产中文 | 国产黄a三级三级三级看三级男男 | 一本一道无码中文字幕精品热 | 久久久久久久久国产精品一区 | 国产av人人夜夜澡人人爽麻豆 | 依人综合网 | 毛片在线免费视频 | 日韩欧美亚洲视频 | a级片在线免费观看 | 一区二区免费看 | 亚洲国产精品无码久久久 | 欧美日韩中 | 18欧美性xxxx极品hd | 亚洲av综合色区无码二区爱av | 狠狠鲁影院 | 亚洲av成人精品毛片 | 久久久久人妻精品色欧美 | 神马久久香蕉 | 日本精品视频 | 日韩一区免费观看 | 国产a久久 | 亚洲高潮| 国内自拍在线 | 最新av不卡 | 久久久国产一区二区三区 | 性巴克成人免费网站 | 中文字幕在线播放视频 | 亚洲欧美精品午睡沙发 | 日本乱子伦xxxx | 夜夜成人| 中文字幕乱码一区二区三区 | 一级黄色播放 | 天堂中文字幕免费一区 | 环太平洋3:泰坦崛起 | 中文字幕在线1 | caopeng视频| 日本美女性生活视频 | 亚洲一级在线 | 国产欧美中文字幕 | 午夜精品久久久久久久久久久久 | 一个人看的www视频在线观看 | 这里只有精品66 | 精品动漫一区二区三区在线观看 | 久久久久国产精品人妻 | 色综合久久久久久久 | 天天躁日日躁狠狠很躁 | 91日韩在线视频 | 国产 日韩 欧美 精品 | 风韵多水的老熟妇 | 全程偷拍露脸中年夫妇 | 中文字幕av播放 | 潘金莲一级淫片aaaaa武则天 | 亚洲乱色熟女一区二区 | 天天综合干 | 久久久亚洲天堂 | 四虎4hu永久免费网站影院 | 99自拍网 | 一区不卡在线观看 | 琪琪成人 | 在线看片福利 | 国产精品色在线 | 国产亚洲制服欧洲高清一区 | 嘿嘿射在线 | 精品一区二区视频 | 天天射寡妇 | 日韩欧美一区在线观看 | 四虎www | 中国老太婆性做爰 | 99re6在线精品视频免费播放 | 91最新在线视频 | 久久午夜夜伦鲁鲁片 | 大尺度摸揉捏胸床戏视频 | 玩弄人妻少妇500系列 | 国产区在线观看 | 羞羞的软件 | 91在线免费看 | 中文字幕在线播放一区二区 | 91久久精品夜夜躁日日躁欧美 | 亚洲va中文字幕 | 亚洲精品久久久久久久蜜桃臀 | 日韩在线观看网址 | 天堂影音 | 99久久精品免费视频 |