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

如何解决Jetpack Compose WebView加载TradingView URL空白问题?

解决Jetpack Compose WebView加载TradingView图表空白问题

针对你遇到的Jetpack Compose中WebView加载TradingView URL空白,但XML WebView正常的问题,可尝试以下针对性修复:

1. 补充WebView关键配置项

TradingView组件依赖较多WebView特性,现有配置缺少部分必要项,添加以下设置:

settings.apply {
    // 保留原有配置,新增以下内容
    javaScriptCanOpenWindowsAutomatically = true // 部分组件依赖JS打开新窗口的能力
    databaseEnabled = true // 启用数据库存储
    setAppCacheEnabled(true) // 组件可能依赖临时缓存
    allowFileAccess = true
    setGeolocationEnabled(true)
    // Android 11+ 需开启跨域资源访问
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
        setAllowCrossOriginRequests(true)
    }
}

2. 启用第三方Cookie支持

TradingView依赖第三方Cookie加载资源,在WebView初始化时添加Cookie配置:

CookieManager.getInstance().apply {
    setAcceptCookie(true)
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        setAcceptThirdPartyCookies(this@apply, true)
    }
}

3. 修复AndroidView的URL更新逻辑

Compose的AndroidView factory仅在首次创建时执行,若selectedCoin变化导致URL更新,WebView不会自动重新加载。添加update块处理URL变化:

AndroidView(
    factory = { /* 原有WebView创建代码 */ },
    update = { webView ->
        if (webView.url != url) {
            webView.loadUrl(url)
        }
    },
    modifier = Modifier.fillMaxWidth().height(400.dp)
)

4. 验证URL有效性

确保selectedCoin?.symbol不为空,避免生成无效URL,添加空值判断:

val url = selectedCoin?.symbol?.let { sym ->
    "https://s.tradingview.com/widgetembed/?frameElementId=tradingview_76d87&symbol=${sym}USD&interval=D&hidesidetoolbar=1&hidetoptoolbar=1&symboledit=1&saveimage=1&toolbarbg=F1F3F6&studies=[]&hideideas=1&theme=Dark&style=1&timezone=Etc/UTC&studies_overrides={}&overrides={}&enabled_features=[]&disabled_features=[]&locale=en&utmsource=coinmarketcap.com&utm_medium=widget&utm_campaign=chart&utm_term=BTCUSDT"
} ?: ""

// 空URL时显示占位符
if (url.isNotEmpty()) {
    TradingChartWebView(url = url)
} else {
    Text("请选择加密货币")
}

5. 添加JS控制台日志排查

通过WebChromeClient捕获JS错误,精准定位加载失败原因:

webChromeClient = object : WebChromeClient() {
    override fun onConsoleMessage(consoleMessage: ConsoleMessage): Boolean {
        Log.d("WebViewJS", "${consoleMessage.message()} -- 行号: ${consoleMessage.lineNumber()} 来源: ${consoleMessage.sourceId()}")
        return super.onConsoleMessage(consoleMessage)
    }
}

完整修改后的TradingChartWebView代码

@SuppressLint("SetJavaScriptEnabled")
@Composable
fun TradingChartWebView(url: String) {
    val context = LocalContext.current

    AndroidView(
        factory = {
            WebView(context).apply {
                settings.apply {
                    javaScriptEnabled = true
                    domStorageEnabled = true
                    loadWithOverviewMode = true
                    useWideViewPort = true
                    cacheMode = WebSettings.LOAD_NO_CACHE
                    mixedContentMode = WebSettings.MIXED_CONTENT_ALWAYS_ALLOW
                    userAgentString = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" // 更新为较新UA
                    // 新增配置
                    javaScriptCanOpenWindowsAutomatically = true
                    databaseEnabled = true
                    setAppCacheEnabled(true)
                    allowFileAccess = true
                    setGeolocationEnabled(true)
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
                        setAllowCrossOriginRequests(true)
                    }
                }

                // 启用第三方Cookie
                CookieManager.getInstance().apply {
                    setAcceptCookie(true)
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                        setAcceptThirdPartyCookies(this@apply, true)
                    }
                }

                webChromeClient = object : WebChromeClient() {
                    override fun onConsoleMessage(consoleMessage: ConsoleMessage): Boolean {
                        Log.d("WebViewJS", "${consoleMessage.message()} -- 行号: ${consoleMessage.lineNumber()} 来源: ${consoleMessage.sourceId()}")
                        return super.onConsoleMessage(consoleMessage)
                    }
                }

                webViewClient = object : WebViewClient() {
                    override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
                        Log.d("WebView", "开始加载: $url")
                    }

                    override fun onPageFinished(view: WebView?, url: String?) {
                        Log.d("WebView", "加载完成: $url")
                    }

                    override fun onReceivedError(
                        view: WebView?,
                        request: WebResourceRequest?,
                        error: WebResourceError?
                    ) {
                        Log.e("WebView", "加载错误: ${error?.description}")
                    }
                }

                loadUrl(url)
            }
        },
        update = { webView ->
            if (webView.url != url) {
                webView.loadUrl(url)
            }
        },
        modifier = Modifier.fillMaxWidth().height(400.dp)
    )
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 03:47:25