WebView坑總結(jié)(上)

在移動端開發(fā)中,一定多多少少會用到WebView,而安卓的碎片化也對Webview造成了或多或少的影響,畢竟不同Android版本的Webview內(nèi)核也不一樣。

今天就總結(jié)一下,我在webview中踩的坑,附帶自己的解決方案or思路。

希望朋友們以后少跳坑。

(webview能做多逼真?推薦澎湃新聞,打開開發(fā)人員選項-顯示布局邊界 你就知道)

0.推薦先行閱讀

Android 瀏覽器內(nèi)核研究與探秘:(復(fù)制到手機(jī)瀏覽器打開)

http://blog.csdn.net/column/details/android-browser.html

14年的總結(jié),時間比較遠(yuǎn),作為入門讀物是可以的。

Android WebView Memory Leak:(復(fù)制到手機(jī)瀏覽器打開)

https://my.oschina.net/zhibuji/blog/100580

大概講了一下泄漏的原因及其研究。

=========================分割線=================

1.webview的內(nèi)存泄漏。

是的,webview會內(nèi)存泄漏,這是我萬萬沒想到的,在我對app進(jìn)行優(yōu)化的時候,首先就對這個坑產(chǎn)生了懷疑,一個控件怎么就????

前文鏈接已經(jīng)有了介紹,我這里就不說啥了。

我在app中集成了LeakCanary進(jìn)行監(jiān)控內(nèi)存泄漏

(LeakCanary是啥....

https://www.liaohuqiu.net/cn/posts/leak-canary-read-me/

不用謝,方便各位年底跳槽能談笑風(fēng)生—。=)

經(jīng)常彈出某activity發(fā)生泄漏,最終指向webview。

一般來說,我們寫一個簡單的demo,渲染某個網(wǎng)頁。布局是這樣的

image

一個progressbar用來顯示網(wǎng)頁加載進(jìn)度,一個webview鋪滿屏幕。

代碼中 webview.load(url)即可。

是的,在了解到webview會內(nèi)存泄漏前,我都是這么寫的,以至于后邊填坑的時候,填了很多...

解決方案:

首先,布局里不要有webview,webview在你需要的時候,通過代碼創(chuàng)建,不需要的時候就抹去。布局里只要存在一個給 webview做容器的webContainer就行了。

image

比如我這里用一個FrameLayout做父布局,用來承載webview。

在需要用webview的時候,手動創(chuàng)建

image

然后把webview加到父容器里。實現(xiàn)的效果也是一樣的,不過這里依舊有一個坑,這樣的寫法,在調(diào)試的時候,網(wǎng)頁里的alert彈框是看不到的,這個坑我后邊會講。

然后該咋渲染咋渲染,在不需要這個webview的時候,比如onDestroy的時候

image

把該webview從父容器里remove掉,首先眼不見為凈。接著處理webview在渲染時可能帶來的垃圾。

image

記住,這里也有坑,webview.pauseTimers貌似是全局影響,也就是用了一次以后,接下來的webview都會受影響,我在開發(fā)的時候,封裝使用了這個api,渲染某個網(wǎng)頁,destroy,再渲染,此時該網(wǎng)頁渲染不出,一直處于黑屏。

包括webview.clearCache,貌似也會造成這樣的狀況,這個我沒有詳細(xì)往下追究,源碼的說明我也只是看得懂個global單詞(真是英語還給老師還得干干凈凈)。

按!順!序!執(zhí)行以上代碼,能有效徹底的干掉webview,

PS:如果先執(zhí)行webview.destroy(),后邊webview均會報異常!!

以上就是解決webview內(nèi)存泄漏的方法。

2..WebView頁面中播放了音/視頻,退出Activity后仍有聲音。

首先,你可以這樣簡單驗證,A activitiy 進(jìn)入 web activitiy,web activitiy加載某個視頻網(wǎng)站,播放視頻,然后按返回鍵返回 A activity,(保證你按返回是finish web activity)

在有的機(jī)型上,返回A后,仍然可以聽見web有播放視頻的聲音,很詭異,我的理解是,該webview并沒有隨web activity被銷毀,webview還在播放cache里的內(nèi)容。

我不知道我這個理解對不對,但是這樣的現(xiàn)象顯然是不允許出現(xiàn)的。

最簡單的方法,webView.destroy()。

然而,坑就在這里。

直接銷毀webview,

控制臺報錯(不會引起崩潰)

java.lang.Throwable:

Error: WebView.destroy() called while still attached!

這就為什么webview要按1方法寫的原因,先從父容器里remove再銷毀。

有的朋友可能會問,在onDestroy的時候webview.load(about:blank)不就好了么,是的,這樣確實不會有聲音播放了,但是...你都已經(jīng)對webview進(jìn)行處理了,不差最后destroy這一步吧?

3.初始化webview配置中的那些坑。

如注釋,對webview進(jìn)行定制(部分坑會在下午詳細(xì)講)

3-1.webChromeClient,我的理解是主要用來處理效果的,如js里的alert,加載進(jìn)度的監(jiān)聽。

3-2.webViewClient,我的理解是主要用來處理網(wǎng)頁事件的,比如web的開始加載回調(diào),加載結(jié)束回調(diào),加載錯誤的回調(diào)。

3-3 websetting,顧名思義web的一些設(shè)置,比如是否允許js注入,是否允許縮放。

image

好了,講坑。

兩個client的坑我開個專題吐槽。

3-3的設(shè)置坑先吐槽。

縮放功能的坑:

setBuiltInZoomControls(true)

setDisplayZoomControls(true)

本身是用來告訴用戶你進(jìn)行了頁面縮放的,但是這兩個同時開,當(dāng)縮放按鈕顯示在webview上的時候,你finish這個activity,應(yīng)用崩潰,是的,不信可以試一試,log我就不放了,因為當(dāng)時播cctv5的界面,朝廷臺沒做移動端適配,所以我開了這兩個開關(guān),然后就T_T。所以兩個開關(guān),要么都不開,要么只開前者。

緩存的坑

setDomStorageEnable(true)

關(guān)閉這個,無法播放部分網(wǎng)站的視頻,比如PPTV,因為我當(dāng)時沒開(默認(rèn)關(guān)閉),被上一個開發(fā)懟了,是的,那個嘲諷會讓我diu更lei加lou努mou力。

cookies的坑

setMixedContentMode

image

在Lollipop以前,混合內(nèi)容模式是默認(rèn)always_allow的,21以后就默認(rèn)normal

這就導(dǎo)致21以上的機(jī)型在播放某些網(wǎng)站的視頻,只有菊花一直在loading。

而且控制臺的數(shù)據(jù)很奇怪,跳出這個坑,經(jīng)驗值加1。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容