Jetpack Compose中如何为WebView实现WebAppInterface(JavaScript接口)?
解决Jetpack Compose中WebView的JavascriptInterface调用失效问题
嘿,我一眼就揪出问题所在了——你漏了最关键的一步:给WebView开启JavaScript支持!虽然你加了@SuppressLint("SetJavaScriptEnabled")注解,但并没有实际在WebView的设置里打开这个开关,这直接导致网页里的JS代码根本没法和Android端的接口交互。
我来帮你把代码修正一下,顺便给你几个实用的优化建议:
1. 核心修复:开启JavaScript支持
在WebView的初始化代码里,一定要加上settings.javaScriptEnabled = true,这是JS能调用Android方法的前提条件。
修正后的完整代码
WebAppInterface类(本身没问题,加个小优化)
/** 实例化接口并设置上下文 */ class WebAppInterface(private val mContext: Context) { /** 从网页显示Toast */ @JavascriptInterface // 这个注解必须加,缺一不可 fun showToast(toast: String) { // 改用Application Context,避免潜在的内存泄漏 Toast.makeText(mContext.applicationContext, toast, Toast.LENGTH_SHORT).show() } }
WebPageScreen Composable(关键修改在这里)
@SuppressLint("SetJavaScriptEnabled") @Composable fun WebPageScreen(urlToRender: String) { AndroidView(factory = { context -> WebView(context).apply { layoutParams = ViewGroup.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT ) webViewClient = WebViewClient() // 🌟 关键修复:开启JavaScript支持 settings.javaScriptEnabled = true // 可选:用Application Context替代Activity Context,降低内存泄漏风险 addJavascriptInterface(WebAppInterface(context), "Android") loadUrl(urlToRender) } }, update = { webView -> // 🌟 优化:只有当URL变化时才重新加载,避免不必要的页面刷新 if (webView.url != urlToRender) { webView.loadUrl(urlToRender) } }) }
2. 额外排查技巧(如果还是不行的话)
如果修复后还是调用不了,可以加个WebChromeClient来查看JS控制台的错误信息,帮你精准定位问题:
webView.webChromeClient = object : WebChromeClient() { override fun onConsoleMessage(consoleMessage: ConsoleMessage?): Boolean { Log.d("WebViewJS", "${consoleMessage?.message()} -- 行号:${consoleMessage?.lineNumber()}") return super.onConsoleMessage(consoleMessage) } }
这样如果JS里出现"Android is not defined"之类的错误,你就能在Logcat里直接看到了。
3. 确认你的HTML/JS代码没问题
你提供的HTML代码是正确的,按钮点击会触发showAndroidToast,进而调用Android.showToast,这部分完全不用修改。
按照上面的步骤调整后,应该就能正常弹出Toast了!
内容的提问来源于stack exchange,提问作者duckduck
相关产品推荐
相关产品推荐

