Flutter webview 崩溃率上升怎么办?我的分析与解决方案
# 前言
我们 App
的 Flutter
版本从 3.27.4
升级到 3.29.3
并上线后,发现 Firebase Crashlytics
平台上多了一个仅 iOS
端才会的船新崩溃异常~
完整错误为:
Fatal Exception: NSInternalInconsistencyException
Completion handler passed to -[FWFNavigationDelegate webView:didReceiveAuthenticationChallenge:completionHandler:] was not called
除此之外,也有如下两个差不多的异常,只是没这个 AuthenticationChallenge
的多。
Completion handler passed to -[webview_flutter_wkwebview.NavigationDelegateImpl webView:didReceiveAuthenticationChallenge:completionHandler:] was not called
Completion handler passed to -[webview_flutter_wkwebview.NavigationDelegateImpl webView:decidePolicyForNavigationResponse:decisionHandler:] was not called
崩溃的主要原因就是这些代理方法被调用后,其 completionHandler
必须也得被执行,否则就崩给你看。
相应的
issue
: https://github.com/flutter/flutter/issues/102476 (opens new window)
很奇怪,issue
是 2022
年提的,提出人当时使用的 Flutter
版本是 2.10.4
,直至今天这期间都有人断断续续提出在不同的 Flutter
版本上出现过,而我们是在升级至 3.29.3
才出现的~
经测试,目前最新版本的 Flutter 3.35.6
和 webview_flutter_wkwebview 3.23.1
依旧可以复现。
# 复现
我们 App 涉及崩溃的设备有 98% 发生在后台状态
根据以往的经验,基本上可以断定是发生在上滑后杀掉 App
的那一刻,所以复现步骤也很简单:
1、Xcode
打全局断点并运行项目
2、进入内嵌页后,网页还在加载时立即上滑,再杀掉 App
即可
不过这也并不是百分之百复现的,既看时机,也看人,我也就十来次操作复现一次~
下图是我复现时的记录输出
可以看到崩溃时有多个 completionHandler
还没有被调用
# 修复
基于上述内容,基本上可以断定这个崩溃其实对用户来说是无感的,但是对我们 App
的崩溃率指标是敏感的,所以在官方修复之前,必须得有临时解决方案。
有两种方案,一是通过 Firebase
过滤掉此类崩溃,想法很好,但是 Firebase
并没有直接提供过滤功能,根据官方文档的说明,只能关闭自动收集崩溃上报功能,然后完全自定义上报异常,简直了,一个对用户无感的崩溃,不至于冒这么大的风险~
于是,Plan B
启动!
众所周知,iOS
是有黑魔法的,而刚好我之前就是搞 iOS
的。
核心思路:
- 通过
Method Swizzling
将涉及崩溃的代理方法进行交换,进而监听方法调用和控制其completionHandler
的调用 - 在代理方法被调用时将
completionHandler
记录起来 - 在
completionHandler
被调用时删除记录 - 在
App
即将被杀掉时,对所有还未被调用的completionHandler
执行调用
这个代码的实现过程就不带大家一步步分析了,有兴趣的小伙伴可以自行查看源码。
我已将修复代码进行了封装并发布了包
https://github.com/LinXunFeng/flutter_webview_completion_fix (opens new window)
接下来看看如何使用
# 使用
添加依赖安装即可,无需其它额外配置,凑是这么方便~
dependencies:
webview_completion_fix: ^0.0.1
如果你想验证修复是否生效,可以在 ios/Runner/Info.plist
添加如下配置开启日志
<key>WCFEnableLogging</key>
<true/>
开启后如图会有 [WCF]
打头的日志输出
如倒数第 3
行所示,当杀掉 App
时,有 2
个 completionHandler
还未被调用,并进行挽救调用防止崩溃。
# 最后
经过验证,我们新版本的 App
已经没有上报此类异常了~
好了,开源不易,如果你也觉得这个库好用,请不吝给个 Star
👍 ,并多多支持!
https://github.com/LinXunFeng/flutter_webview_completion_fix (opens new window)
本篇到此结束,感谢大家的支持,我们下次再见! 👋

- 01
- Flutter - Melos Pub workspaces 实践10-12
- 02
- Flutter - 详情页初始锚点与优化08-24
- 03
- Flutter - 详情页 TabBar 与模块联动?秒了!08-17