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执行过程中的错误。
额外排查点
- 通过
onConsoleMessage查看网页控制台日志,确认sweetalert2等JS资源是否加载成功、有没有语法错误。 - 若网页使用ES6+语法,Android 7.0以下设备需引入JS polyfill,确保WebView兼容。
- 确认
domStorageEnabled已开启,部分JS框架依赖本地存储实现功能。
内容的提问来源于stack exchange,提问作者Ikrar Khaera
相关产品推荐
相关产品推荐

