当前位置: 首页 > news >正文

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

背景:

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.mrgr.cn/news/58206.html

相关文章:

  • cmd中运行python manage.py makemigrations
  • 前端算法:树(力扣144、94、145、100、104题)
  • gin入门教程(2):go安装以及初始目录构建
  • 2万字长文,如何成为一个“懂”AI 的产品经理?零基础入门到精通,收藏这一篇就够了
  • 【含开题报告+文档+PPT+源码】基于vue框架的东升餐饮点餐管理平台的设计与实现
  • 专题十五_字符串_算法专题详细总结
  • 开放式耳机推荐千元左右有哪些?开放式耳机推荐品牌
  • 迅为3A6000_7A2000核心主板龙芯全国产处理器龙芯3A5000等龙架构处理器软件兼容
  • 绝绝子工具
  • Java每日面试题(前端Vue拓展)(day20)
  • Web大学生网页作业成品——抗击疫情网页设计与实现(HTML+CSS)(4个页面)
  • 时间数据可视化基础实验(南丁格尔玫瑰图)——Python热狗大胃王比赛前三名分析
  • mysql原理、部署mysql主从+读写分离、监控mysql主从脚本
  • 【傻瓜教程】阿里云图标引入自己的项目
  • 电动机的启动,制动及保护
  • 6 C语言编程基础:注释的重要性与使用
  • 【工具】新手礼包之git相关环境包括中文的一套流程{收集和整理},gitlab的使用
  • [专有网络VPC]高可用虚拟IP(HaVip)
  • 基于SpringBoot的时装购物系统【源码】+【论文】
  • 没有密码,如何取消Word文档的只读模式?
  • RJ45 网口--内部有/没有变压器的连接器
  • MySQL 之 索引
  • BLE 协议之传输层
  • 一文梳理:如何构建并优化GPU云算力中心?
  • 微服务之网关、网关路由、网关登录校验
  • django restful API