WebView渲染異常導致閃退問題的解決方案
背景:
App主頁面使用了大量WebView容器(10個以上)顯示圖表信息,最新發(fā)現(xiàn)bugly上面出現(xiàn)一些關于瀏覽器Native Crash,如下:



經(jīng)排查,是WebView渲染失敗導致Crash,可以通過webView.loadUrl("chrome://crash")模擬。
解決方法:
1、通過設置WebViewClient,重寫onRenderProcessGone()返回值,強制返回true,表示在WebView發(fā)生異常時,自己處理,這樣App就不會出現(xiàn)Crash。這么做App雖然沒有Crash,但是主頁面的WebView內容卻看不到了,看到的是白色/黑色背景,體驗極差。
2、要想解決WebView內容不可見問題,還需要在Web出現(xiàn)異常的時候,移除原有Web容器,重新創(chuàng)建一個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
}
}本項目橋接使用的是DSBridge三方庫,在創(chuàng)建Web容器需要設置addJavascriptObject(),即reloadFun函數(shù)。
注意事項:
1、同一個頁面只要有一個渲染異常,會導致所有Web容器異常,所以所有Web容器都要重新創(chuàng)建,不可以根據(jù)Web可見狀態(tài)只創(chuàng)建可見的Web。
2、在使用的時候,原有的Web容器已被移除,需要使用最新的Web容器,否則就會報錯。上述代碼中,新的Web容器id跟移除的一樣,所以也很容易拿到新的Web容器,代碼如下:
/**
* 獲取真實的webView,之前的web可能被銷毀
* @param id web id
*/
private fun getRealWebView(id: Int): ReportWebView {
return mBinding.root.findViewById(id)
}總結
到此這篇關于WebView渲染異常導致閃退問題解決方案的文章就介紹到這了,更多相關WebView渲染異常閃退內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Android在WebView中調用系統(tǒng)下載的方法
這篇文章主要為大家詳細介紹了Android在WebView中調用系統(tǒng)下載的簡單使用,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-05-05
Android編程之界面跳動提示動畫效果實現(xiàn)方法
這篇文章主要介紹了Android編程之界面跳動提示動畫效果實現(xiàn)方法,實例分析了Android動畫效果的布局及功能相關實現(xiàn)技巧,具有一定參考借鑒價值,需要的朋友可以參考下2015-11-11
Android實現(xiàn)把文件存放在SDCard的方法
這篇文章主要介紹了Android實現(xiàn)把文件存放在SDCard的方法,涉及Android針對SDCard的讀寫技巧,具有一定參考借鑒價值,需要的朋友可以參考下2015-09-09
Android獲取RecyclerView滑動距離方法詳細講解
RecyclerView是Android一個更強大的控件,其不僅可以實現(xiàn)和ListView同樣的效果,還有優(yōu)化了ListView中的各種不足。其可以實現(xiàn)數(shù)據(jù)縱向滾動,也可以實現(xiàn)橫向滾動(ListView做不到橫向滾動)。接下來講解RecyclerView的用法2023-01-01
Android 實現(xiàn)把bitmap圖片的某一部分的顏色改成其他顏色
這篇文章主要介紹了Android 實現(xiàn)把bitmap圖片的某一部分的顏色改成其他顏色,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-04-04
Android Intent啟動別的應用實現(xiàn)方法
我們知道Intent的應用,可以啟動別一個Activity,那么是否可以啟動別外的一個應用程序呢,答案是可以的2013-04-04

