解決在硬體加速下WebView切換閃屏的問題

2021-08-10 12:32:50 字數 1360 閱讀 6516

**:

問題描述

在利用webview進行開發時,遇到了這樣乙個問題,即在兩個fragment中分別嵌入兩個webview,切換fragment時,頁面會閃爍並伴隨有黑塊,使用者體驗非常糟糕。

解決歷程

既然問題的根源找到了,接下來就要知道怎麼解決問題了。查詢了很多資料部落格,給出的解決方案都是一致的,手動關閉硬體加速。於是我照做,關閉後重新執行,fragment切換果然順暢了,沒有出現閃屏,問題完美解決。如果你以為這樣就結束了,那你就太年輕了,真正的難題才剛剛開始。閃爍的bug是解決了,但只要你細心,就會發現頁面上下滾動的時候會卡頓,而之前開啟硬體加速的時候是沒有這個問題的。

這就難辦了,硬體加速到底是應該開啟還是關閉,這是個問題。我想,硬體加速是在android 3.0之後新引入的,必然是google對android系統做出的優化,而又在android 4.0版本預設開啟,充分說明了其重要性,所以肯定是不能關閉的。這樣的話就又回到了起點的那個bug,怎麼解決閃屏的問題。這裡我反覆搜尋了很多資訊,也有不少人遇到了同樣的問題,但是都沒有乙個很好的解決方案,我甚至以為這是webview的乙個尚未解決的bug,不是我等區區幾行**就可以搞得定的。

後來我在一次偶然中發現,fragment切換的時候,會走onattach()和ondetach()等生命週期方法(這裡我使用的是fragmenttabhost來控制fragment的切換),為了驗證我的猜測,我將**進行重構,底部的導航按鈕使用radiobutton,activity初始化時載入所有fragment,通過radiobutton來控制各個fragment的hide()和show(),這樣做的好處就是不會觸發fragment的任何生命週期方法。執行結果驗證了我的猜想是正確的,之前使用fragmenttabhost來切換fragment時會一次次地呼叫attach()和detach()方法,每一次切換,view都會進行一次重繪,這也就是在硬體加速下,導致webview閃爍的罪魁禍首了。而改進過後的**,雖然會一次性把所有的fragment都載入進記憶體,加大了記憶體的消耗,但切換fragment時不用對view進行重繪,恰好是解決這個bug的最佳方式。

既然了解了bug的產生原因,解決方案自然就不止一種。我們點開fragmenttabhost的原始碼,可以很明顯地看到,dotabchanged()這個方法就是控制fragment切換的核心邏輯。我們只要自定義乙個myfragmenttabhost,將原始碼複製進來,把所有的attach()和detach()方法改為show()和hide()就可以了。

自定義myfragmenttabhost原始碼如下,可直接使用,

public class myfragmenttabhost extends tabhost implements tabhost.ontabchangelistener {

private final arraylist

webview的白屏,和硬體加速

android的硬體加速 android從3.0 api level 11 開始,在繪製view的時候支援硬體加速,充分利用gpu的特性,使得繪製更加平滑,但是會多消耗一些記憶體。開啟或關閉硬體加速 由於硬體加速自身並非完美無缺,所以android提供選項來開啟或者關閉硬體加速,預設是關閉。可以在4...

webview的白屏,和硬體加速

android的硬體加速 android從3.0 api level 11 開始,在繪製view的時候支援硬體加速,充分利用gpu的特性,使得繪製更加平滑,但是會多消耗一些記憶體。開啟或關閉硬體加速 由於硬體加速自身並非完美無缺,所以android提供選項來開啟或者關閉硬體加速,預設是關閉。可以在4...

硬體加速 Pr開始支援A卡硬體加速

上週,amd正式推出旗下針對專業工作站平台的高效能處理器執行緒系列者pro系列,而聯想p620台式工作站更是對該系列處理器進行了首發。不過,該工作站配備的是英偉達顯示卡。由於amd顯示卡也是從近兩年才開始翻身,因此在專業軟體的支援方面稍顯落後。以如今使用最為廣泛的premiere pro軟體為例,其...