WebView渲染异常导致闪退解决方案

news/2024/10/26 7:52:35/

背景:

App主页面使用了大量WebView容器(10个以上)显示图表信息,最新发现bugly上面出现一些关于浏览器Native Crash,如下:



经排查,是WebView渲染失败导致Crash,可以通过webView.loadUrl("chrome://crash")模拟。

解决方法:

1、通过设置WebViewClient,重写onRenderProcessGone()返回值,强制返回true,表示在WebView发生异常时,自己处理,这样App就不会出现Crash。这么做App虽然没有Crash,但是主页面的WebView内容却看不到了,看到的是白色/黑色背景,体验极差。

2、要想解决WebView内容不可见问题,还需要在Web出现异常的时候,移除原有Web容器,重新创建一个Web容器,代码如下:

class ReportWebView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) : wendu.dsbridge.BaseWebView(context, attrs) {var reloadFun: ((any: ReportWebView) -> Unit)? = nullprivate var parentViewGroup: ViewGroup? = nullinit {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?.isVisibleval lp = this.layoutParams// 移除旧的 WebViewval index = indexInParent()if (parentViewGroup != null) {parentViewGroup?.removeView(this)}destroy()// 销毁// 重新创建 WebViewval newWebView = ReportWebView(context)reloadFun?.invoke(newWebView)newWebView.reloadFun = reloadFunnewWebView.id = idnewWebView.layoutParams = lpnewWebView.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三方库,在创建Web容器需要设置addJavascriptObject(),即reloadFun函数。

注意事项:

1、同一个页面只要有一个渲染异常,会导致所有Web容器异常,所以所有Web容器都要重新创建,不可以根据Web可见状态只创建可见的Web。

2、在使用的时候,原有的Web容器已被移除,需要使用最新的Web容器,否则就会报错。上述代码中,新的Web容器id跟移除的一样,所以也很容易拿到新的Web容器,代码如下:

/*** 获取真实的webView,之前的web可能被销毁* @param id web id*/
private fun getRealWebView(id: Int): ReportWebView {return mBinding.root.findViewById(id)
}


http://www.ppmy.cn/news/1542050.html

相关文章

【赵渝强老师】Hive的内部表与外部表

Hive是基于HDFS之上的数据仓库,它把所有的数据存储在HDFS中,Hive并没有专门的数据存储格式。当在Hive中创建了表,可以使用load语句将本地或者HDFS上的数据加载到表中,从而使用SQL语句进行分析和处理。 Hive的数据模型主要是指Hiv…

Halcon 多相机统一坐标系(标定)

多相机统一坐标系是指将多个不同位置的相机的图像采集到同一个坐标系下进行处理和分析的方法。 在计算机视觉和机器视觉领域中,多相机统一坐标系被广泛应用于三维重建、立体视觉、目标跟踪等任务中。 以gen_binocular_rectification_map(生成描述图像映…

React六官方文档总结三脱围机制

代码下载 React官网已经都是函数式组件文档,没有类组件文档,但是还是支持类组件这种写法。 脱围机制 ref 引用值 当希望组件“记住”某些信息,但又不想让这些信息 触发新的渲染 时,可以使用 ref 。 给组件添加 ref 1、通过从…

从0开始深度学习(14)——模型选择、欠拟合、过拟合

① 模型在训练数据上拟合的比在潜在分布中更接近的现象,就叫过拟合(overfitting) ② 用于对抗过拟合的技术称为正则化(regularization) 1 训练误差和泛化误差 ①训练误差(training error)&…

【linux】ELKB安装token过期

问题 elastic启动时候生成的token 有效期只有30分钟。 30分钟后提示: Couldnt configure Elastic Generate a new enrollment token or configure manually. 解决 进入安装目录 cd /usr/local/elasticsearch/elasticsearch-8.8.1/binll 重新生成 ./elasticsear…

python主流框架Django:ORM框架关联查询与管理器

目录 注意 使用前要调用之前的模型类 F对象 Q对象 聚合函数 排序 关联查询(连表查询) 修改 删除 查询集 QuerySet 注意 使用前要调用之前的模型类 F对象 之前的查询都是对象的属性与常量值比较,两个属性怎么比较呢? 答:使用 "F对象&quo…

高并发场景下解决并发数据不一致

简单的场景: 全量数据更新的情况下, 不在乎同一秒的请求都必须要成功, 只留下最新的更新请求数据 方案常用的是 1、数据库增加时间戳标识实现的乐观锁, 请求参数从源头带上微秒或者毫秒时间戳数据库存储, 然后在更新SQL语句上比较 (数据库的时间 < 参数传递的时间) 例如: A…

机器学习与神经网络的当下与未来

一、机器学习与神经网络的发展前景 &#xff08;一&#xff09;各领域的具体应用和作用 生产制造领域 在工业生产中&#xff0c;机器学习和神经网络被用于质量控制。例如&#xff0c;通过对产品外观图像的分析&#xff0c;神经网络能够以极高的准确率识别出产品表面的瑕疵。像…