View 的軟件繪制和硬件繪制
View 的軟件繪制和硬件繪制
開(kāi)發(fā) android 應(yīng)用的時(shí)候,常有一些問(wèn)題會(huì)涉及到 “硬件加速” ,例如在某個(gè)頁(yè)面上打開(kāi)/關(guān)閉硬件加速來(lái)解決特定問(wèn)題。那么今天就簡(jiǎn)單說(shuō)下具體 硬件繪制 相關(guān)的一些內(nèi)容。
應(yīng)用里的頁(yè)面是以一棵棵 View 樹(shù)表示的,其中每個(gè) view 代表屏幕上一塊內(nèi)容。而實(shí)際顯示的內(nèi)容便是 view 繪制出來(lái)的,view 的繪制是從 view 樹(shù)的邏輯控制者——也就是對(duì)應(yīng)的 ViewRootImpl 對(duì)象觸發(fā)的。其中包括軟件繪制和硬件繪制兩種方式。
當(dāng) ViewRootImpl 設(shè)置了 開(kāi)啟硬件加速 的時(shí)候,會(huì)使用硬件繪制的方式進(jìn)行繪制,否則使用軟件繪制。硬件繪制和軟件繪制類似于對(duì)同一個(gè)接口的兩種實(shí)現(xiàn)。其基本的繪制步驟都一樣的,只是兩種繪制方式里每個(gè)步驟實(shí)現(xiàn)不同。
View 的軟件繪制
View 的軟件繪制和硬件繪制的核心是 draw,也就是通常所說(shuō)的 measure-layout-draw 中的 draw ,也就是繪制流程。即遍歷 view 樹(shù),自上向下遍歷依次調(diào)用 draw。其中會(huì)涉及 view 的繪制過(guò)程以及向下分發(fā)等。
在此 draw 的流程之前以及之后,需要進(jìn)行一些處理。大家都知道 draw 是依賴于畫(huà)布 canvas 的,canvas 只有在獲取之后才可以進(jìn)行 draw,并且 draw 完成后需要將 canvas 交給實(shí)際繪制到屏幕上的下一個(gè)環(huán)節(jié)。
而 View 的軟件繪制和硬件繪制的差別,就在于 draw 之外的其他流程的實(shí)現(xiàn),軟件繪制步驟里,獲取 canvas 之后,view 樹(shù)可以直接接觸到 canvas 對(duì)象,對(duì)其進(jìn)行修改繪制。繪制完畢后,ViewRootimpl 將 canvas 交給對(duì)應(yīng)的處理者繪制到屏幕上。
但是硬件繪制則不是如此,硬件繪制流程里,ViewRootImpl 并不會(huì)獲取 canvas 并且讓 view 樹(shù)對(duì)其進(jìn)行改動(dòng)。而是將這個(gè)過(guò)程都交給另一個(gè)專門的類來(lái)“代理”,即不獲取 canvas,使用另一個(gè)類里的 canvas;不對(duì) view 進(jìn)行繪制,將繪制動(dòng)作封裝成數(shù)據(jù)交給另一個(gè)類;也不進(jìn)行下一步的處理,而是將下一步通知的能力也交給另一個(gè)類。這種情況下,ViewRootImpl 就只需要在 draw 的時(shí)候通知那個(gè)代理類開(kāi)始工作,并且提供一些必要的信息就可以了。
這是一個(gè)解耦的操作,同時(shí)可以將 繪制 動(dòng)作變得可擴(kuò)展了。
View 的硬件加速
當(dāng)我們?cè)?manifest 文件里聲明某個(gè) activity 的時(shí)候制定了開(kāi)啟硬件加速的時(shí)候,該 activity 的繪制便會(huì)使用硬件加速,其對(duì)應(yīng)的便是 ViewRootImpl 的硬件加速開(kāi)啟。ViewRootImpl 的硬件加速如果開(kāi)啟的話,會(huì)在進(jìn)行 view 樹(shù)根節(jié)點(diǎn)的繪制的時(shí)候,采用硬件繪制的方式進(jìn)行。
浙公網(wǎng)安備 33010602011771號(hào)