android圖形系統詳解五:Android繪製模式

來源:互聯網
上載者:User

 當硬加速被啟用,Android架構利用一個新的繪製模式來把你的應用呈現到螢幕,這個模式利用了一個顯示列表.要完全理解顯示列表以及它如何影響你的應用,先要理解android如何在非硬加速下繪製View.下面的小節描述了軟加速的和硬加速的繪製models.

軟體繪製模式

 

  在軟體繪製模式,view按以下兩步進行繪製:

  • 1使整個View層級都變得無效

  • 2繪製所有的View層級

  任何時候一個應用需要更新部分UI時,它應在任何改變了內容的View上調用invalidate()(或它的任一變體),使介面無效的訊息在整個View層級中傳播以計算應被繪製的螢幕地區(髒地區).之後Android系統繪任View層級中所有與髒地區有交集的View. 不幸的是,這種繪製模式有兩個缺點:

  • 第一,這個模式需要在每個繪製路徑中都執行很多代碼.比如,如果你的應用在一個button上調用了invalidate()並且這個button位於另一個view之上,即使這個View沒有變化,Android系統也會繪製這個View.

  • 第二個問題是這個繪製模式可能隱藏你應用中的bug.因為Android系統會繪製與髒地區有交集的view們,那麼一個你改變了內容的view可能在沒有被調用invalidate()時也會被重繪了.當這種情況發生時,你只能依賴那個需要重繪的view來獲得正確的行為.但這個行為可能在你每次修改你的應用時都會改變.因此,在任何你修改了資料或狀態而影響到繪製代碼的時候,你總是應該在你的自訂view上調用invalidate().

  註:Androidview們會在它們的屬性被改變時自動調用invalidate(),比如一個TextView的背景和文本改變時.

硬加速繪製模式

 

  Android系統依然使用invalidate()和draw()來請求螢幕更新並畫出views,但是對實際的繪製處理卻不一樣.現在不是在收到繪製命令立即執行了,而是Android系統把繪製命令記錄到顯示列表中,這個列表中包含了View層級的繪製代碼的輸出.另一個最佳化是Android系統只需為那些通過invalidate()標記為髒的View記錄和更新顯示列表.沒有被invalidated的Views可以簡單地使用先前的顯示列表中的記錄進行重繪.新的繪製模式包含三個階段:

  • 1使整個View層級都無效

  • 2記錄並更新顯示列表

  • 3畫顯示列表

  使用此模式,你再不能依靠讓View與髒地區交界而使它的draw()方法被調用.要保證Android系統記錄下view的顯示列表,你必須調用invalidate().忘記這樣做會導致一個view總是一個模樣,即使改變了它.但這是一個很容易被找出的bug.

  使用顯示列表還對提升動畫效能有益,因為設定了某個屬性,比如alpha或rotation等,不再需invalidating目標view(自動做了).這個最佳化也會應用到擁有顯示列表的view上(當你的應用被硬加速時的任何view).例如,假設有一個LinearLayout包含了一個ListView和一個Button,ListView位於Button之上,LinearLayout的顯示列表看起來如下:

  • DrawDisplayList(ListView)

  • DrawDisplayList(Button)

  假設現在你想改變ListView的opacity,在調用了ListView的setAlpha(0.5f)後,顯示列表現在包含如下項:

  • SaveLayerAlpha(0.5)

  • DrawDisplayList(ListView)

  • Restore

  • DrawDisplayList(Button)

  ListView複雜的繪製過程沒有被執行,而是僅更新了更簡單的LinearLayout的顯示列表.如果在一個未硬加速的應用中,列表和它爹的繪製代碼都會被重新執行.

不支援的繪製操作

 

  當啟用了硬加速,2D呈現管道會支援通用的Canvas繪製操作,也支援不常用的操作.所有的繪製操作被用來呈現widgets,layouts以及通用進階視覺效果,比如反光和平鋪紋理.下面的列表描述了已知的不能被硬加速支援的繪製操作:

  • Canvas

    • clipPath()

    • clipRegion()

    • drawPicture()

    • drawPosText()

    • drawTextOnPath()

    • drawVertices()

  • Paint

    • setLinearText()

    • setMaskFilter()

    • setRasterizer()

  另外,還有一些操作的行為在啟用硬加速後會變得不一樣:

  • Canvas

    • clipRect():異或,差異和反差異剪下都被忽略.3D變換不應用到剪下框中

    • drawBitmapMesh():顏色數組被忽略

    • drawLines():反鋸齒不被支援

    • setDrawFilter():可以設定,但被忽略

  • Paint

    • setDither():被忽略

    • setFilterBitmap():濾鏡一直啟用

    • setShadowLayer():僅對文本起作用

  • ComposeShader

    • ComposeShader只能包含不同類型的著色器(比如一個BitmapShader和一個LinearGradient,不能是兩個BitmapShader)

    • ComposeShader不能包含ComposeShader

  如果你的應用被這些缺少的特性或限制影響了,你可以通過調用setLayerType(View.LAYER_TYPE_SOFTWARE,null)為受影響的部分關閉硬加速.用此方法,你依然可以在其它地方享用到硬加速.

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.