基本的優(yōu)化總結(三)

導言

這節(jié)主要講的是UI優(yōu)化方面關于GPU相關的知識,比方說過渡繪制和硬件加速

過渡繪制

在Google的教程中我們可以看到人家專門提了過渡繪制的問題,這個在平時使用的時候也非常的簡單,直接找到手機的開發(fā)者選項媚创,然后打開GPU過渡繪制即可


打開選項位置

啟用后的效果

這里可以看到一些控件上面有一些顏色,這些顏色就是用于反饋過渡繪制的程度
1.白色:沒有過渡繪制
2.藍色:過渡繪制一次
3.淺綠色:過渡繪制兩次
4.淺紅色:過渡繪制三次
5.紅色:過渡繪制四次及以上

過渡繪制所導致問題就是在繪圖的時候可能會重復繪制一些用戶并不能看到的像素點,比方說一些互相重疊的視圖荤西,從而造成性能方面的損失

常用的解決方案

    <style name="easy_overdraw" parent="AppTheme">
        <item name="android:windowBackground">@null</item>
    </style>

因為視圖默認是展示在window上面,而window本身就有一個背景,在很多時候邪锌,你不能確定窗體的背景是否有展示的必要勉躺,而且完全可以用更高層級的視圖背景來替代,從而降低過渡繪制

此外就是注意自身的布局觅丰,減少不必要的重疊以及背景饵溅,一般原則上就是層級越低的布局優(yōu)先設置背景,否則才考慮頂層布局設置背景妇萄。
減少重疊有一個方案蜕企,這個可以參考官方的DrawerLayout中的代碼

        if (drawingContent) {
            final int childCount = getChildCount();
            for (int i = 0; i < childCount; i++) {
                final View v = getChildAt(i);
                if (v == child || v.getVisibility() != VISIBLE
                        || !hasOpaqueBackground(v) || !isDrawerView(v)
                        || v.getHeight() < height) {
                    continue;
                }

                if (checkDrawerViewAbsoluteGravity(v, Gravity.LEFT)) {
                    final int vright = v.getRight();
                     //只選擇了抽屜右邊的區(qū)域
                    if (vright > clipLeft) clipLeft = vright;
                } else {
                    final int vleft = v.getLeft();
                    //只選擇了抽屜左邊的區(qū)域
                    if (vleft < clipRight) clipRight = vleft;
                }
            }
            canvas.clipRect(clipLeft, 0, clipRight, getHeight());
        }

重點關注clipRect方法

    /**
     * Intersect the current clip with the specified rectangle, which is
     * expressed in local coordinates.
     *
     * @param left   The left side of the rectangle to intersect with the
     *               current clip
     * @param top    The top of the rectangle to intersect with the current clip
     * @param right  The right side of the rectangle to intersect with the
     *               current clip
     * @param bottom The bottom of the rectangle to intersect with the current
     *               clip
     * @return       true if the resulting clip is non-empty
     */
    public boolean clipRect(int left, int top, int right, int bottom) {
        return nClipRect(mNativeCanvasWrapper, left, top, right, bottom,
                Region.Op.INTERSECT.nativeInt);
    }

從注釋中可以看出,實際上就是指定繪制的區(qū)域冠句,也就是說可以通過該方法來優(yōu)化繪制的范圍轻掩。
DrawerLayout就是通過這個方法,來避免當抽屜出現(xiàn)的時候重復繪制內(nèi)容被遮擋的部分懦底,從而優(yōu)化過渡繪制

硬件加速

平炒侥粒看視頻之類的都知道有一個硬件加速,在Android中同樣也可以使用基茵,通過View的

    setLayerType(LAYER_TYPE_HARDWARE,null);

可以指定開啟硬件加速層奋构,看一下具體的注釋

    /**
     * <p>Indicates that the view has a hardware layer. A hardware layer is backed
     * by a hardware specific texture (generally Frame Buffer Objects or FBO on
     * OpenGL hardware) and causes the view to be rendered using Android's hardware
     * rendering pipeline, but only if hardware acceleration is turned on for the
     * view hierarchy. When hardware acceleration is turned off, hardware layers
     * behave exactly as {@link #LAYER_TYPE_SOFTWARE software layers}.</p>
     *
     * <p>A hardware layer is useful to apply a specific color filter and/or
     * blending mode and/or translucency to a view and all its children.</p>
     * <p>A hardware layer can be used to cache a complex view tree into a
     * texture and reduce the complexity of drawing operations. For instance,
     * when animating a complex view tree with a translation, a hardware layer can
     * be used to render the view tree only once.</p>
     * <p>A hardware layer can also be used to increase the rendering quality when
     * rotation transformations are applied on a view. It can also be used to
     * prevent potential clipping issues when applying 3D transforms on a view.</p>
     *
     * @see #getLayerType()
     * @see #setLayerType(int, android.graphics.Paint)
     * @see #LAYER_TYPE_NONE
     * @see #LAYER_TYPE_SOFTWARE
     */
    public static final int LAYER_TYPE_HARDWARE = 2;

注釋中提到,開啟硬件加速層可以很有效的進行視圖樹繪制緩存拱层,降低繪制的次數(shù)弥臼,這樣對于一些復雜的動畫來說是一個非常大的優(yōu)化,也就是說在使用動畫的時候應該考慮開啟硬件加速進行優(yōu)化
但是注意硬件加速會帶來其他的問題根灯,比方說在GPU層會有明顯的內(nèi)存占用增加


Android profiler中Memory的反饋

可以看到GPU層所使用的內(nèi)存大量增加径缅,所以一般來說在動畫結束之后需要關閉硬件加速層,從而去釋放這一部分的內(nèi)存烙肺,比方說

    text1.setLayerType(View.LAYER_TYPE_HARDWARE,null)
    val animator = ValueAnimator.ofFloat(0.0f,90.0f)
    animator.addUpdateListener {
         text1.rotation = it.animatedValue as Float
    }
    animator.addListener(object :Animator.AnimatorListener{
         override fun onAnimationRepeat(animation: Animator?) {

         }

        override fun onAnimationCancel(animation: Animator?) {
             text1.setLayerType(View.LAYER_TYPE_NONE,null)
         }

         override fun onAnimationStart(animation: Animator?) {

         }

         override fun onAnimationEnd(animation: Animator?) {
             text1.setLayerType(View.LAYER_TYPE_NONE,null)
         }
     })
     animator.setTarget(text1)
     animator.repeatCount = ValueAnimator.INFINITE
     animator.start()

總結

這部分主要是介紹了過渡繪制的處理以及硬件加速的使用纳猪,是關于GPU層的一種優(yōu)化手段

文章系列:
基本的優(yōu)化總結(一)
基本的優(yōu)化總結(二)
基本的優(yōu)化總結(三)
基本的優(yōu)化總結(四)
基本的優(yōu)化總結(五)
基本的優(yōu)化總結(六)
基本的優(yōu)化總結(七)

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市桃笙,隨后出現(xiàn)的幾起案子氏堤,更是在濱河造成了極大的恐慌,老刑警劉巖搏明,帶你破解...
    沈念sama閱讀 219,427評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件鼠锈,死亡現(xiàn)場離奇詭異,居然都是意外死亡星著,警方通過查閱死者的電腦和手機购笆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來虚循,“玉大人同欠,你說我怎么就攤上這事样傍。” “怎么了铺遂?”我有些...
    開封第一講書人閱讀 165,747評論 0 356
  • 文/不壞的土叔 我叫張陵衫哥,是天一觀的道長。 經(jīng)常有香客問我襟锐,道長炕檩,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,939評論 1 295
  • 正文 為了忘掉前任捌斧,我火速辦了婚禮笛质,結果婚禮上,老公的妹妹穿的比我還像新娘捞蚂。我一直安慰自己妇押,他們只是感情好,可當我...
    茶點故事閱讀 67,955評論 6 392
  • 文/花漫 我一把揭開白布姓迅。 她就那樣靜靜地躺著敲霍,像睡著了一般。 火紅的嫁衣襯著肌膚如雪丁存。 梳的紋絲不亂的頭發(fā)上肩杈,一...
    開封第一講書人閱讀 51,737評論 1 305
  • 那天,我揣著相機與錄音解寝,去河邊找鬼扩然。 笑死,一個胖子當著我的面吹牛聋伦,可吹牛的內(nèi)容都是我干的夫偶。 我是一名探鬼主播,決...
    沈念sama閱讀 40,448評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼觉增,長吁一口氣:“原來是場噩夢啊……” “哼兵拢!你這毒婦竟也來了?” 一聲冷哼從身側響起逾礁,我...
    開封第一講書人閱讀 39,352評論 0 276
  • 序言:老撾萬榮一對情侶失蹤说铃,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后嘹履,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體腻扇,經(jīng)...
    沈念sama閱讀 45,834評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,992評論 3 338
  • 正文 我和宋清朗相戀三年植捎,在試婚紗的時候發(fā)現(xiàn)自己被綠了衙解。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片阳柔。...
    茶點故事閱讀 40,133評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡焰枢,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情济锄,我是刑警寧澤暑椰,帶...
    沈念sama閱讀 35,815評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站荐绝,受9級特大地震影響一汽,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜低滩,卻給世界環(huán)境...
    茶點故事閱讀 41,477評論 3 331
  • 文/蒙蒙 一召夹、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧恕沫,春花似錦监憎、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至迄委,卻和暖如春褐筛,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背叙身。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評論 1 272
  • 我被黑心中介騙來泰國打工渔扎, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人信轿。 一個月前我還...
    沈念sama閱讀 48,398評論 3 373
  • 正文 我出身青樓赞警,卻偏偏與公主長得像,于是被迫代替她去往敵國和親虏两。 傳聞我的和親對象是個殘疾皇子愧旦,可洞房花燭夜當晚...
    茶點故事閱讀 45,077評論 2 355