如果Wait for it...a deep dive into Espresso's Idling Resources 的不可靠性是由使用WebChromeClient 引起的,请考虑改用WebViewClient。
我发现当网页完成加载时WebViewClient 会可靠地触发onPageFinished()。 WebChromeClient 和 WebViewClient 相似,但 WebViewClient 更通用,因为 WebChromeClient 处理 WebView 的 Chrome 特定方面(请参阅 What's the difference between setWebViewClient vs. setWebChromeClient?)。
在示例项目https://github.com/mosofsky/how-to-coredux 中,我将onPageFinished() 函数注册到WebView,如下所示:
playVideoWebView.webViewClient = object : WebViewClient() {
override fun shouldOverrideUrlLoading(view: WebView, url: String): Boolean {
return false
}
override fun onPageFinished(view: WebView?, url: String?) {
if (null != url && url != ABOUT_URL) {
// the next line dispatches an action that calls decrement()
howToViewModel.dispatchAction(LoadVideo_Finish)
}
}
}
我希望这会有所帮助,尽管我承认我没有解决您提到的其他缺点。至于缺少getWebChromeClient(),现在好像可以了。至于需要特定的 WebView 实例,我不知道如何避免。不知何故,您必须让 WebView 在完成加载后减少空闲资源计数器。似乎任何解决方案都必须以某种方式接触 WebView 的特定实例才能完成此注册过程。一些开发人员可能会觉得用CountingIdlingResource 对increment() 和decrement() 的调用来乱扔他们的生产代码很乏味或不合适。
为了尽量减少使用空闲资源计数调用检测的代码量,您可以将这些调用隔离为我称之为异步代码的“副作用”。为此,我发现使用 Redux 数据存储非常有帮助,例如 CoRedux。当异步动作开始时,您可以将状态更新为“进行中”;当它结束时,清除“进行中”标志。 “副作用”可以是任何监听“进行中”的机制。 CoRedux 确实有一个称为“副作用”的构造,您可以使用它,但任何响应状态变化的机制都可以。
在how-to-coredux 示例项目的副作用中,它像这样调用increment() 和decrement():
when (action) {
is Initialize_Start, is ShowVideoFragment_Start, LoadVideo_Start, HideVideoFragment_Start -> {
espressoTestIdlingResource.increment()
}
Initialize_Finish, ShowVideoFragment_Finish, LoadVideo_Finish, HideVideoFragment_Finish -> {
espressoTestIdlingResource.decrement()
}
}
通过将空闲资源逻辑隔离为副作用,整个 Android 项目可以依赖于单个代码来分别在每次任何异步 UI 事件开始/结束时分别调用 increment()/decrement()。