Android WebView 仅在第一次失败

标签 android kotlin webview android-webview

我有一个显示本地 Assets 网站的 Android 应用程序,它只有 1 个带有通用 webview 的 Activity :

我正在使用 WebViewAssetLoader作为提供文件的本地方式,我面临的一个非常令人沮丧的问题是,当它第一次安装的应用程序在 WebView 中加载内容失败时,如果我终止应用程序并再次运行它,它会完美运行(但我不能说用户这样做),如果应用程序是由 Android 工作室第二次安装,它可以工作,但如果应用程序从未安装过,它总是会失败。

这是logcat的结果

2019-11-18 16:58:40.439 21492-21492/? E/Zygote: isWhitelistProcess - Process is Whitelisted 2019-11-18 16:58:40.439 21492-21492/? E/Zygote: accessInfo : 1 2019-11-18 16:58:40.628 21492-21544/com.my.app.dev.debug E/GraphicsEnv: Failed to get gpu service 2019-11-18 16:58:40.805 21492-21492/com.my.app.dev.debug E/chromium: [ERROR:filesystem_posix.cc(89)] stat /data/user/0/com.my.app.dev.debug/cache/WebView/Crashpad: No such file or directory (2) 2019-11-18 16:58:40.805 21492-21492/com.my.app.dev.debug E/chromium: [ERROR:filesystem_posix.cc(62)] mkdir /data/user/0/com.my.app.dev.debug/cache/WebView/Crashpad: No such file or directory (2) 2019-11-18 16:58:45.237 21492-21658/com.my.app.dev.debug E/AssetHelper: Unable to open asset path: dist/



这是加载 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 包和版本),但希望这可能会有所帮助。

2019-11-18 16:58:40.439 21492-21492/? E/Zygote: isWhitelistProcess - Process is Whitelisted 2019-11-18 16:58:40.439 21492-21492/? E/Zygote: accessInfo : 1

2019-11-18 16:58:40.628 21492-21544/com.my.app.dev.debug E/GraphicsEnv: Failed to get gpu service

2019-11-18 16:58:40.805 21492-21492/com.my.app.dev.debug E/chromium: [ERROR:filesystem_posix.cc(89)] stat /data/user/0/com.my.app.dev.debug/cache/WebView/Crashpad: No such file or directory (2)

2019-11-18 16:58:40.805 21492-21492/com.my.app.dev.debug E/chromium: [ERROR:filesystem_posix.cc(62)] mkdir /data/user/0/com.my.app.dev.debug/cache/WebView/Crashpad: No such file or directory (2)



这些日志不是发生崩溃的原因,它是 WebView 本身的问题,与 WebViewAssetLoader 没有任何关系。 .因此,请确保在您的设备上更新到最新的 WebView 和 Chrome 版本(WebView 是通过应用商店定期更新的,这与 android 框架不同)。确保这不是 WebViewAssetLoader问题,尝试构建没有所有 WebViewAssetLoader 的相同应用程序代码,看看是否仍然发生相同的崩溃。

2019-11-18 16:58:45.237 21492-21658/com.my.app.dev.debug E/AssetHelper: Unable to open asset path: dist/



这是唯一与 androidx.webkit.WebViewAssetLoader 相关的行.我假设您正在加载的内容正在尝试打开一个文件夹 /assets/dist/那不存在。但是,这不应导致任何崩溃。

除此之外,您的代码还有一些注意事项:
  • 你不必守卫WebViewAssetLoader对于 API 级别 >= 21,您应该可以将其用于 API >= 14 .

  • 对于 WebViewClient#shouldInterceptRequest ,如果您覆盖该方法的两个版本而不是放弃使用 WebViewAssetLoader 会更好完全适用于较旧的 API:
    @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))
    }
    
  • 不要将此设置设置为 true:
  •   webView!!.settings.allowUniversalAccessFromFileURLs = true
    

    我假设您正在为 WebViewAssetLoader 的情况启用此设置。不使用。此设置高度discouraged因为它允许 CORS对于 javascript。如果您曾经在 WebView 中加载第 3 方内容,这将是一个安全风险,因为它使任何 javascript 代码能够访问任何私有(private)应用程序文件。这实际上是主要问题WebViewAssetLoader正在尝试解决,因此您不需要 - 实际上也不应该 - 设置 allowUniversalAccessFromFileURLs = true当您使用 WebViewAssetLoader .

    此外,为了使事情更加安全,如果您使用 WebViewAssetLoader 访问所有本地应用程序 Assets 文件,您还应该将其设置为 false:
    webView!!.settings.allowFileAccess = false
    

    关于Android WebView 仅在第一次失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58924345/

    相关文章:

    android - 如何在 android 布局中使用多个 MathJax 公式 View

    java - 将全局静态变量声明为 null 是一个好习惯吗?

    java - 如何在 WebView Android 中加载 url 时显示进度条

    android - 动画开始时的动画菜单项 "jumps"

    Android SQLite 约束冲突。 Try/Catch 抓不到

    java - 找不到具有不同 buildvariant 的包名称 "...."的匹配客户端

    android - 读取 QR 码导致 kotlin 应用程序崩溃

    java - 使用谓词的通用集合过滤

    react-native - 使用 POST 时不支持 Source.headers

    android - 拦截来自 Android Java/JNI 的网络调用