我有一个显示本地 Assets 网站的Android应用程序,它只有1个 Activity 与共同的webview:
我使用WebViewAssetLoader作为服务文件的本地方式,我面临的最大麻烦是,如果我安装了该应用程序,并且第一次无法将其加载到WebView中,则该应用程序被我杀死了并运行它再次可以完美运行(但是我不能说用户可以这样做),如果该应用程序是由Android Studio第二次安装的,它也可以运行,但是如果从未安装过该应用程序,则它总是会失败。
这是logcat的结果
这是加载WebView的代码
private fun initializeWebViewSettings() {
webView!!.setBackgroundColor(Color.TRANSPARENT)
webView!!.settings.javaScriptEnabled = true
webView!!.settings.javaScriptCanOpenWindowsAutomatically = true
webView!!.settings.domStorageEnabled = true
webView!!.settings.allowFileAccess = true
webView!!.settings.allowContentAccess = true
webView!!.settings.allowUniversalAccessFromFileURLs = true
webView!!.settings.setGeolocationEnabled(true)
setWebViewClient()
setWebViewChromeClient()
webView!!.visibility = View.INVISIBLE
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
//ONLY API_LEVEL >= 21 can use WebViewAssetLoader
assetLoader = WebViewAssetLoader.Builder()
.addPathHandler("/assets/", AssetsPathHandler(this))
.addPathHandler("/res/", ResourcesPathHandler(this))
.build()
webView!!.loadUrl(Constants.WEB_URL_SERVED)
}
else{
webView!!.loadUrl(Constants.WEB_URL_LOCAL)
}
}
经过研究后,发现这是与此问题相关的已知错误,但已解决了较新版本的Chrome,我正在使用Android API 28(最新)在Galaxy Note10上进行测试
有没有人遇到过类似的问题?任何线索将不胜感激。
最佳答案
我的回答不能直接解决您的问题,因为它需要更多的上下文(更多的日志以及您使用的Webview软件包和版本),但是希望这可以有所帮助。
这些日志不是崩溃发生的原因,这是WebView本身存在的问题,与WebViewAssetLoader
没有任何关系。因此,请确保更新到设备上的最新WebView和Chrome版本(与Android框架不同,WebView会通过应用商店定期更新)。为了确保这不是WebViewAssetLoader
问题,请尝试构建没有所有WebViewAssetLoader
代码的相同应用,然后查看是否仍然发生相同的崩溃。
这是与androidx.webkit.WebViewAssetLoader
相关的唯一行。我假设您正在加载的内容正在尝试打开一个不存在的/assets/dist/
文件夹。但是,这不会导致任何崩溃。
除此之外,您的代码还有一些注意事项:
WebViewAssetLoader
,您应该可以将其用于API >= 14。 对于
WebViewClient#shouldInterceptRequest
,如果重写该方法的两个版本,而不是完全放弃对旧API使用WebViewAssetLoader
,那就更好了:@RequiresApi(21)
override fun shouldInterceptRequest(
view: WebView?,
request: WebResourceRequest?
): WebResourceResponse? {
return assetLoader.shouldInterceptRequest(request.url)
}
@SuppressWarnings("deprecation") // suppress the warning if your target build API is lower than 21
override fun shouldInterceptRequest(
view: WebView?,
request: String?
): WebResourceResponse? {
return assetLoader.shouldInterceptRequest(Uri.parse(request))
}
webView!!.settings.allowUniversalAccessFromFileURLs = true
我假设您在未使用
WebViewAssetLoader
的情况下启用了此设置。此设置的高度为discouraged,因为它允许javascript的CORS。如果您曾经在WebView中加载第三方内容,这将带来安全隐患,因为它会使任何javascript代码都能够访问任何私有(private)应用程序文件。这实际上是WebViewAssetLoader
试图解决的主要问题,因此当您使用allowUniversalAccessFromFileURLs = true
时,您不需要-并且实际上不应设置WebViewAssetLoader
。此外,为了使事情更加安全,如果您使用
WebViewAssetLoader
访问所有本地应用程序 Assets 文件,还应将其设置为false:webView!!.settings.allowFileAccess = false