天天看点

Android使用webview怎么加载uri_珍爱生命,远离安卓WebView

2019.01.01 更新:解决方法

2019.01.06 更新:另外一个同类型bug

众所周知,安卓的WebView是个非常坑的控件,这想必不用我说多。花式内存泄漏、生命周期混乱之类,碎片化等等的bug我就不提了

然而今天一个发现实在是让我大跌眼镜

众所周知,WebView的saveState与restoreState充满了bug。Bug如此之多以至于Google在2014年去除了Webview.restoreState()恢复显示数据的功能

https://developer.android.com/reference/android/webkit/WebView.html#restoreState(android.os.Bundle)​developer.android.com

If it is called after this WebView has had a chance to build state (load pages, create a back/forward list, etc.) there may be undesirable side-effects. Please note that this method no longer restores the display data for this WebView.

然而,然而,在安卓里Activity、Fragment和各种控件重建又是家常便饭的事。一个重建把用户数据搞丢了怎么办?于是有两大对策:

  1. 当缩头乌龟,我就是不重建,这辈子都不会重建。于是有了这一句Google在文档里强烈反对的代码(Google:你们又不肯丢数据又不肯崩布局让我很为难啊)
android:configChanges="orientation|screenSize"
           

我不理会系统的onConfigurationChange事件不就完了

2. 实在不行要重建了,我人肉写一套逻辑来恢复数据可以了吧?Bug多就多,反正常见的重建事件都给我缩头躲过去了,剩下的不就是一些特例吗,针对那些特例写写就完了。

正常来说这也就够了,直到我今天发现,除了旋转屏幕、分屏这些常见事件会触发重建以外......

插拔蓝牙键盘也会触发重建!而且这玩意还不算在screenSize这个类型里的!上面那句代码拦不住这个事件

如果没考虑到这种情况触发的重建,那么等接下来用到这个WebView的时候,鬼知道这个WebView里面的状态已经变成了什么。然后再evaluate几个Javascript,当场爆炸。

可能是插拔蓝牙键盘这种东西不是每个人都会测试的,所以搜了一时半会居然搜不到相关讨论。这一下子就让人后背发凉了,今天冒出来个插拔蓝牙键盘,明天后天还指不定又冒出来个啥事件又绕过去了。

至于有多坑爹,看下面的测试

既然网上搜不到讨论,那很有可能很多已有项目也没想到这点,于是我针对我目前感兴趣的Markdown编辑器测试了一下

以下测试在一加6+H2OS 9.0.2上进行

  1. MarkdownEditors

首先是广受好评的MarkdownEditors,这个项目只在Markdown预览里用了WebView。进入预览界面,插入蓝牙键盘。嗯,好像没事?你再点点后退键试试

运气好的话你还能后退到主界面,大部分情况下直接就弹出来“MarkdownEditors”已停止运行,整个应用直接炸了,GG

2. MarkdownX

接下来是另一个广受好评的MarkdownX。这个项目预览界面和编辑界面貌似都用了WebView。进入预览或者编辑界面,插入蓝牙键盘,界面当场崩溃,GG

不过还好应用没炸

3. MarkNote(马克笔记)

马克笔记只在预览界面使用了WebView,但非常好评的是,没有大bug。除了看到一半时插入键盘会被强行滚回到页面顶部以外。

4. 为知笔记

为知笔记不开源,所以到底怎么实现的我也不知道。我只知道,在为知笔记的建立一个“文本”笔记再插上蓝牙键盘会有以下两个情况随机发生

i. 应用当场爆炸

ii. 应用没爆,只是刷新了一下,看起来没问题。然而再点点返回键试试,发现按钮没了响应

大概率用了WebView

5. 蚂蚁笔记(Leanote)

蚂蚁笔记是我很看好的开源笔记软件。蚂蚁笔记在“RichText”模式下插拔蓝牙键盘,好消息是,应用不会崩溃,界面不会没响应。

坏消息是,丢失所有未保存的数据,外加强制回到页面最顶端。

6-9. 易写 & Dropdown Paper & Notion & JotterPad

没有bug。不过这几位都不开源,我猜他们是不是没用到WebView

可以看到,中招的不少。由于后面几个应用没开源,不知道用没用到WebView,无法统计总的中招率。但是让我猜的话,我猜中招率为4/5

声明一下,这篇文章不是为了喷某个软件,作者深知“开源软件就是你行你上”的精神。作者只是表达自己对安卓WebView的强烈负面情绪。

再用原生WebView我吃X!!! (哎,真香......个屁,我还真得用)

目前作者还没开始找解决办法,android:configChanges这么多,插拔蓝牙键盘到底是哪个,我也没深入研究过。有了解的大佬欢迎来评论

Android使用webview怎么加载uri_珍爱生命,远离安卓WebView

Update:解决方案,在android:configChanges里同时加上keyboard|keyboardHidden这两个事件

另外有空了我就去那几个开源项目开Issue去

珍爱生命,远离WebView

Update:

果然这种重建事件简直让人后背发凉,有老哥又发现一个:Github Issue

btw,拔插数据线也有类似的问题

我测试了一下,在12月更新之后,拔插充电线会导致uimode的变化,Activity重启

原因已找到:开启了省电模式之后,uimode&Configuration.UI_MODE_NIGHT_MASK的值为UI_MODE_NIGHT_YES,接上数据线后,这个值变为UI_MODE_NIGHT_NO,因而导致Activity重启

这种省电模式+版本加持的特殊重建简直是要了命