WebView渲染異常導(dǎo)致閃退問題的解決方案
背景:
App主頁(yè)面使用了大量WebView容器(10個(gè)以上)顯示圖表信息,最新發(fā)現(xiàn)bugly上面出現(xiàn)一些關(guān)于瀏覽器Native Crash,如下:
經(jīng)排查,是WebView渲染失敗導(dǎo)致Crash,可以通過(guò)webView.loadUrl("chrome://crash")模擬。
解決方法:
1、通過(guò)設(shè)置WebViewClient,重寫onRenderProcessGone()返回值,強(qiáng)制返回true,表示在WebView發(fā)生異常時(shí),自己處理,這樣App就不會(huì)出現(xiàn)Crash。這么做App雖然沒有Crash,但是主頁(yè)面的WebView內(nèi)容卻看不到了,看到的是白色/黑色背景,體驗(yàn)極差。
2、要想解決WebView內(nèi)容不可見問題,還需要在Web出現(xiàn)異常的時(shí)候,移除原有Web容器,重新創(chuàng)建一個(gè)Web容器,代碼如下:
class ReportWebView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) : wendu.dsbridge.BaseWebView(context, attrs) { var reloadFun: ((any: ReportWebView) -> Unit)? = null private var parentViewGroup: ViewGroup? = null init { webViewClient = CustomWebViewClient() } override fun onAttachedToWindow() { super.onAttachedToWindow() parentViewGroup = parent as? ViewGroup } private inner class CustomWebViewClient : WebViewClient() { override fun onRenderProcessGone(view: WebView?, detail: RenderProcessGoneDetail?): Boolean { // 所有的web都crash,所以都需要重建 recreateWebViewAndReload(view) return true } } private fun recreateWebViewAndReload(view: WebView?) { val originalUrl = view?.url// 原始webView地址 val isVisible = view?.isVisible val lp = this.layoutParams // 移除舊的 WebView val index = indexInParent() if (parentViewGroup != null) { parentViewGroup?.removeView(this) } destroy()// 銷毀 // 重新創(chuàng)建 WebView val newWebView = ReportWebView(context) reloadFun?.invoke(newWebView) newWebView.reloadFun = reloadFun newWebView.id = id newWebView.layoutParams = lp newWebView.isVisible = isVisible.nullOr(false) originalUrl?.let { newWebView.loadUrl(it) } // 將新的 WebView 添加回布局中 parentViewGroup?.addView(newWebView, index) // 更新引用 parentViewGroup = newWebView.parent as? ViewGroup } private fun indexInParent(): Int { return parentViewGroup?.indexOfChild(this) ?: -1 } }
本項(xiàng)目橋接使用的是DSBridge三方庫(kù),在創(chuàng)建Web容器需要設(shè)置addJavascriptObject(),即reloadFun函數(shù)。
注意事項(xiàng):
1、同一個(gè)頁(yè)面只要有一個(gè)渲染異常,會(huì)導(dǎo)致所有Web容器異常,所以所有Web容器都要重新創(chuàng)建,不可以根據(jù)Web可見狀態(tài)只創(chuàng)建可見的Web。
2、在使用的時(shí)候,原有的Web容器已被移除,需要使用最新的Web容器,否則就會(huì)報(bào)錯(cuò)。上述代碼中,新的Web容器id跟移除的一樣,所以也很容易拿到新的Web容器,代碼如下:
/** * 獲取真實(shí)的webView,之前的web可能被銷毀 * @param id web id */ private fun getRealWebView(id: Int): ReportWebView { return mBinding.root.findViewById(id) }
總結(jié)
到此這篇關(guān)于WebView渲染異常導(dǎo)致閃退問題解決方案的文章就介紹到這了,更多相關(guān)WebView渲染異常閃退內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Android在WebView中調(diào)用系統(tǒng)下載的方法
這篇文章主要為大家詳細(xì)介紹了Android在WebView中調(diào)用系統(tǒng)下載的簡(jiǎn)單使用,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-05-05Android編程之界面跳動(dòng)提示動(dòng)畫效果實(shí)現(xiàn)方法
這篇文章主要介紹了Android編程之界面跳動(dòng)提示動(dòng)畫效果實(shí)現(xiàn)方法,實(shí)例分析了Android動(dòng)畫效果的布局及功能相關(guān)實(shí)現(xiàn)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-11-11Android判斷當(dāng)前App是在前臺(tái)還是在后臺(tái)
這篇文章主要為大家詳細(xì)介紹了Android判斷當(dāng)前App是在前臺(tái)還是在后臺(tái)的方法,感興趣的小伙伴們可以參考一下2016-08-08Android實(shí)現(xiàn)把文件存放在SDCard的方法
這篇文章主要介紹了Android實(shí)現(xiàn)把文件存放在SDCard的方法,涉及Android針對(duì)SDCard的讀寫技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-09-09Android自定義view實(shí)現(xiàn)圓的擴(kuò)散效果
這篇文章主要為大家詳細(xì)介紹了Android自定義view實(shí)現(xiàn)圓的擴(kuò)散效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-01-01Android獲取RecyclerView滑動(dòng)距離方法詳細(xì)講解
RecyclerView是Android一個(gè)更強(qiáng)大的控件,其不僅可以實(shí)現(xiàn)和ListView同樣的效果,還有優(yōu)化了ListView中的各種不足。其可以實(shí)現(xiàn)數(shù)據(jù)縱向滾動(dòng),也可以實(shí)現(xiàn)橫向滾動(dòng)(ListView做不到橫向滾動(dòng))。接下來(lái)講解RecyclerView的用法2023-01-01Android 實(shí)現(xiàn)把bitmap圖片的某一部分的顏色改成其他顏色
這篇文章主要介紹了Android 實(shí)現(xiàn)把bitmap圖片的某一部分的顏色改成其他顏色,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-04-04Android Intent啟動(dòng)別的應(yīng)用實(shí)現(xiàn)方法
我們知道Intent的應(yīng)用,可以啟動(dòng)別一個(gè)Activity,那么是否可以啟動(dòng)別外的一個(gè)應(yīng)用程序呢,答案是可以的2013-04-04