You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

EDC开发的无浏览器Android设备中,如何让WebView运行JavaScript?

解决WebView中JavaScript功能(alert/sweetalert2)失效问题

核心问题分析

你的代码里自定义WebChromeClient时,重写的onJsAlert、onJsConfirm、onJsPrompt方法直接返回true,但没调用JsResult/JsPromptResult的confirm()或cancel()方法。这会导致JavaScript执行到弹窗逻辑时,一直等待WebView返回结果,进而阻塞后续JS代码,最终让alert、sweetalert2这类依赖完整JS执行流程的功能失效。

修改后的代码

private fun webView(url: String) {
    val webView = binding.webView
    val settings = webView.settings

    // 基础JS与WebView配置
    settings.javaScriptEnabled = true
    settings.domStorageEnabled = true
    settings.javaScriptCanOpenWindowsAutomatically = true
    settings.loadsImagesAutomatically = true
    settings.allowFileAccess = true
    settings.allowContentAccess = true
    settings.allowFileAccessFromFileURLs = true
    settings.allowUniversalAccessFromFileURLs = true
    settings.loadWithOverviewMode = true
    settings.useWideViewPort = true
    settings.builtInZoomControls = true
    settings.displayZoomControls = false
    settings.setSupportZoom(true)
    settings.cacheMode = WebSettings.LOAD_DEFAULT
    settings.defaultTextEncodingName = "utf-8"
    settings.pluginState = WebSettings.PluginState.ON
    settings.mixedContentMode = WebSettings.MIXED_CONTENT_ALWAYS_ALLOW
    settings.blockNetworkImage = false
    settings.blockNetworkLoads = false
    settings.databaseEnabled = true
    settings.mediaPlaybackRequiresUserGesture = true
    settings.setGeolocationEnabled(true)
    settings.setSupportMultipleWindows(true)

    webView.requestFocusFromTouch()
    webView.clearCache(true)

    // Cookie处理
    val cookieManager = CookieManager.getInstance()
    cookieManager.removeAllCookies(null)
    cookieManager.setAcceptCookie(true)

    // 自定义WebChromeClient - 正确处理JS交互
    webView.webChromeClient = object : WebChromeClient() {
        override fun onPermissionRequest(request: PermissionRequest) {
            Log.d("onPermissionReq", "permission granted")
            request.grant(request.resources)
        }

        @SuppressLint("ResourceType")
        override fun onJsAlert(
            view: WebView?,
            url: String?,
            message: String?,
            result: JsResult?
        ): Boolean {
            Log.d("cekJsAlert", "on js alert: $message")
            // 必须调用confirm()让JS执行流程继续
            result?.confirm()
            return true // 返回true表示已自定义处理弹窗
        }

        override fun onJsPrompt(
            view: WebView?,
            url: String?,
            message: String?,
            defaultValue: String?,
            result: JsPromptResult?
        ): Boolean {
            Log.d("cekJsAlert", "on js prompt: $message")
            // 如需自定义输入可在此处理,这里默认返回空值
            result?.confirm(defaultValue ?: "")
            return true
        }

        override fun onJsConfirm(
            view: WebView?,
            url: String?,
            message: String?,
            result: JsResult?
        ): Boolean {
            Log.d("cekJsAlert", "on js confirm: $message")
            // 根据业务需求选择confirm()或cancel(),这里默认确认
            result?.confirm()
            return true
        }

        override fun onJsBeforeUnload(
            view: WebView?,
            url: String?,
            message: String?,
            result: JsResult?
        ): Boolean {
            Log.d("cekJsAlert", "on js before load: $message")
            result?.confirm()
            return true
        }

        override fun onConsoleMessage(consoleMessage: ConsoleMessage?): Boolean {
            consoleMessage?.let {
                Log.d("WebViewConsole", "${it.message()} (${it.sourceId()}:${it.lineNumber()})")
            }
            return true
        }
    }

    // 自定义WebViewClient
    webView.webViewClient = object : WebViewClient() {
        @SuppressLint("WebViewClientOnReceivedSslError")
        override fun onReceivedSslError(
            view: WebView?,
            handler: SslErrorHandler?,
            error: android.net.http.SslError?
        ) {
            handler?.proceed() // 忽略SSL错误(仅测试环境使用,生产环境需谨慎)
        }

        @Deprecated("Deprecated in Java")
        override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean {
            url?.let { view?.loadUrl(it) }
            return true
        }

        override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
            Log.d("WebView", "Page started loading: $url")
            binding.loading.progressbarLoading.visibility = VISIBLE
            CookieManager.getInstance().setAcceptThirdPartyCookies(view!!, true)
        }

        override fun onPageFinished(view: WebView?, url: String?) {
            Log.d("WebView", "Page finished loading: $url")
            binding.loading.progressbarLoading.visibility = GONE
        }
    }

    webView.loadUrl(url)
}

关键修改说明

  • 修复JS交互阻塞:在所有JS弹窗回调方法中调用result.confirm()(或cancel()),确保JavaScript执行流程不会中断。
  • 清理冗余配置:删除了重复初始化的默认WebViewClient和WebChromeClient,避免不必要的对象创建。
  • 增强日志排查:优化控制台日志格式,方便定位JS执行过程中的错误。

额外排查点

  1. 通过onConsoleMessage查看网页控制台日志,确认sweetalert2等JS资源是否加载成功、有没有语法错误。
  2. 若网页使用ES6+语法,Android 7.0以下设备需引入JS polyfill,确保WebView兼容。
  3. 确认domStorageEnabled已开启,部分JS框架依赖本地存储实现功能。

内容的提问来源于stack exchange,提问作者Ikrar Khaera

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 06:50:56