最近工作中遇到一个问题,webview中按钮的点击事件没反应,而在微信打开该Url是没问题的,IOS端也没问题,(用的lzyzsd的JsBridge框架)结合项目之前一直偶发bug没响应,于是我拿来看了下代码,和另一个项目对比,发现当前项目注入js的时机是WebViewClient的onLoadResource的回调里,而onLoadResource回调是当页面加载一次资源(js,css,图片等外部资源),在回调加了日志后发现onLoadResource居然被调用了15次,也就是说短时间注入同一组js(其实共要注入两个js文件)多达15次,我在想会不会是短时间内注入次数太多炸掉了webview的一些功能例如事件传递什么的,于是我上网转了一圈都说在WebViewClient的onPageFinished注入js(原项目也是这样),于是我把js注入事件改成在WebViewClient的onPageFinished注入 ,结果那个点击按钮无响应的问题真的就好了
就在我以为事情得到解决的时候他奶奶的另一个问题又来了,另一个模块h5调起原生的方法居然失败了,经过我的排查和祖传的代码注释发现了原来项目有一种场景是在onPageFinished前就要调我原生的方法,换而言之就是我要在onPageFinished之前就注入好js不然应付不了这种场景,于是我又上网翻了一圈以及对比的另外一个项目,发现可以在WebViewClient的onPageStarted注入,但伴随的一个问题是部分机型onPageStarted没有调用,于是我总结JsBridge注入时机的需求:
1.注入时机要尽可能早(onPageFinished太慢了)
2.要避免短时间内大量注入,不然会产生不可预料的BUG
3.要考虑一次注入失败的情况(实验表明这种情况不但有而且还不少)
为此我特意在网上搜了下JsBridge注入的时机,分别是
WebViewClient.onPageFinished
WebViewClient.onPageStarted
WebViewClient.onPageCommitVisible
WebChromeClient.onProgressChanged
WebChromeClient.onReceivedTitle
WebViewClient.onLoadResource
对应加日志打印加载一次页面的回调情况,如图所示:
捕获.PNG
可以看出就第一次调用的节点来看是回调顺序是onProgressChanged(进度10%),onPageStarted,onLoadRecourse,onPageCommitVisible,onPageFinished,并且onPageStarted,onPageCommitVisible,onPageFinished都是只调用一次的,因此要确保尽早注入js的话onProgressChanged(进度10%),onPageStarted,onLoadRecourse都是比较好的注入时机
我最终的解决方案是在onPageStarted注入,并在onLoadRecourse进行补充注入,加入最大注入次数显示(毕竟重复注入只是预防一次注入失败,重复注入3,4次就好)和注入时间间隔(例如100ms),具体应该根据项目做调整,当然了还有其他更好解决方法例如交由前端页面把握注入时机,或者更换DSBridge库(听说JsBridge有些致命BUG并且原作者好久没维护了),这里就不多赘述了
网友评论