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

WebView解析HTML时@Composable函数调用错误的解决方法咨询

解决非@Composable函数中调用含AndroidView的@Composable函数问题

问题分析

你在LaunchedEffect(协程作用域,非直接Composable上下文)中调用带有@Composable注解的loadAndParseWebPageComposable函数触发报错,核心原因是AndroidView属于Composable组件,必须在Composable上下文环境中执行,无法在协程作用域内直接调用。

修复方案

调整代码结构,将loadAndParseWebPageComposable的调用直接放在UI树的条件分支中,同时优化加载逻辑避免重复触发:

@Composable
fun AddProductScreen(viewModel: ProductViewModel, onAddComplete: () -> Unit) {
    var url by remember { mutableStateOf("") }
    var loading by remember { mutableStateOf(false) }
    // 记录用户确认加载的目标URL,避免输入框实时变化触发重复加载
    var targetLoadUrl by remember { mutableStateOf("") }

    Column(modifier = Modifier.padding(16.dp)) {
        TextField(
            value = url,
            onValueChange = { url = it },
            label = { Text("Введите URL товара") },
            modifier = Modifier.fillMaxWidth()
        )
        Spacer(modifier = Modifier.height(16.dp))
        Button(onClick = {
            loading = true
            targetLoadUrl = url
        }) {
            Text("Добавить")
        }
        if (loading) {
            CircularProgressIndicator()
        }

        // 在Composable上下文直接调用WebView加载组件
        if (loading && targetLoadUrl.isNotEmpty()) {
            loadAndParseWebPageComposable(targetLoadUrl, viewModel) {
                loading = false
                targetLoadUrl = "" // 重置目标URL,防止重复触发
                onAddComplete()
            }
        }
    }
}

@Composable
fun loadAndParseWebPageComposable(url: String, viewModel: ProductViewModel, onLoaded: () -> Unit) {
    val context = LocalContext.current

    AndroidView(factory = {
        WebView(context).apply {
            settings.javaScriptEnabled = true
            webViewClient = object : WebViewClient() {
                override fun onPageFinished(view: WebView, loadedUrl: String) {
                    super.onPageFinished(view, loadedUrl)
                    view.evaluateJavascript(
                        "(function() { return document.documentElement.outerHTML })();"
                    ) { html ->
                        viewModel.parseProductHtml(html ?: "")
                        onLoaded()
                    }
                }
            }
            loadUrl(url)
        }
    }, update = { webView ->
        // 仅当URL变更时重新加载,避免无意义刷新
        if (webView.url != url) {
            webView.loadUrl(url)
        }
    })
}

关键调整说明

  • 将loadAndParseWebPageComposable的调用从LaunchedEffect移至UI树的条件判断中,确保其运行在Composable上下文环境内。
  • 新增targetLoadUrl状态变量,分离用户输入的实时URL和确认加载的目标URL,避免输入框内容变化触发重复加载。
  • 在AndroidView的update块中增加URL校验逻辑,优化加载性能。

内容的提问来源于stack exchange,提问作者Mr SkNilPler

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 22:55:02