问题出现
有两种情况:一种情况是打开activity时webview开始加载页面,但是发现加载了一部分后就停止了,余下的一直不再加载。但是当关闭这个activity时发现webview又继续加载了。
第二种情况是webview正常加载,但是进行操作时发现有些操作没有反应。比如接入支付宝国际sdk,未装支付宝app而使用h5页面时出现点击无反应的情况。
问题解析
进过反复测试发现,是因为有两个含有webview的activity:activityA和activityB。在activityA的onPause和onResume中分别有mWebView.pauseTimers()
和mWebView.resumeTimers()
,但是activityB中没有。先打开activityA加载web页面,然后打开activityB,因为activityB没有resumeTimers
,他的部分js未成功加载,所以出现上面的现象。
问题根源
问题的根源就是WebView的pauseTimers()和resumeTimers()这两个方法。它们的源码及注释如下
代码语言:javascript复制/**
* Pauses all layout, parsing, and JavaScript timers for all WebViews. This
* is a global requests, not restricted to just this WebView. This can be
* useful if the application has been paused.
*/
public void pauseTimers() {
checkThread();
mProvider.pauseTimers();
}
/**
* Resumes all layout, parsing, and JavaScript timers for all WebViews.
* This will resume dispatching all timers.
*/
public void resumeTimers() {
checkThread();
mProvider.resumeTimers();
}
复制代码
可以看到这两个方法都是全局的,可以停止所有WebView的加载。所以当打开activityB的时候走了activityA的生命周期onPause,这样执行了pauseTimers()
,而因为是全局的所以作用到所有的webview,所以activityB的webview也被pause而停止了加载,同时因为activityB的生命周期中并没有实现这两个函数,所以在pauseTimers()
后没有执行resumeTimers()
,所以activityB的web页面被pause后也没有恢复,这样就导致了一部分js代码没有加载,这样相关的效果就失效了。
解决方法
通过上面分析,其实我们就知道该如何解决了,在activityB的onPause和onResume中也加入mWebView.pauseTimers()
和mWebView.resumeTimers()
即可。但是像我们前面说的第二种情况,我们使用的是第三方sdk的话,那么我们是没办法对其进行修改的,我们可以将activityA中的mWebView.pauseTimers()
和mWebView.resumeTimers()
方法去掉来保证页面正常。
最后注意,webview还有onPause()
和onResume
这两个方法。这两个方法与pauseTimers()
和resumeTimers()
不同,他们两个是作用范围在当前webview的。而且作用效果也不同:onPause()
会立刻停止当前webview的加载;而pauseTimers()
会停止所有webview的延时加载,即那些等待timeout才执行的function,并且不执行resumeTimers()
就不会加载。