【问题标题】:Wait for result from Coroutine and then use it in Composable function等待 Coroutine 的结果,然后在 Composable 函数中使用它
【发布时间】:2022-10-04 18:53:33
【问题描述】:

我一直在疯狂地试图弄清楚这一点,我只是不确定该怎么做。

我正在创建一个视频抓取工具,它具有以下功能,可以从作为参数提供的 URL 中抓取视频源:

fun scrapeVideoSrcFromUrl(url: String): String? {
    val document = Jsoup.connect(url).get()

    for (element in document.getElementsByTag("script")) {
        if (element.attr("type") == "application/ld+json") {
            val content = element.data()
            val array = JsonParser.parseString(content).asJsonArray

            val embedUrl = Gson().fromJson(array.get(0).asJsonObject.get("embedUrl"), String::class.java)
            var embedId = ""

            for (char in embedUrl.dropLast(1).reversed()) {
                if (char != '/') {
                    embedId += char
                } else {
                    break
                }
            }

            val doc = Jsoup.connect("$RUMBLE_API_URL${embedId.reversed()}").ignoreContentType(true).get()
            val jsonData = doc.getElementsByTag("body").first()?.text()

            val mp4 = JsonParser.parseString(jsonData).asJsonObject.get("u").asJsonObject.get("mp4").asJsonObject.get("url").toString()

            return mp4.replace("\"", "")
        }
    }

    return null
}

我想使用ExoPlayer在某个链接的对话框中显示它,所以我做了以下操作:

@Composable
fun VideoPlayer(videoSrc: String) {
    val context = LocalContext.current

    val exoPlayer = remember {
        ExoPlayer.Builder(context).build().apply {
            setMediaItem(
                MediaItem.fromUri(
                    videoSrc
                )
            )
            prepare()
            playWhenReady = true
        }
    }

    Box(modifier = Modifier.fillMaxSize()) {
        DisposableEffect(key1 = Unit) {
            onDispose {
                exoPlayer.release()
            }
        }

        AndroidView(
            factory = {
                StyledPlayerView(context).apply {
                    player = exoPlayer
                    layoutParams =
                        FrameLayout.LayoutParams(
                            ViewGroup.LayoutParams.MATCH_PARENT,
                            ViewGroup.LayoutParams.MATCH_PARENT
                        )
                }
            }
        )
    }
}

然后,在主要的 Composable 中:

if (openDialog) {
        AlertDialog(
            onDismissRequest = {
                openDialog = false
            },
            title = {
                Column {
                    Text(
                        text = viewModel.currentRumbleSearchResult?.title ?: ""
                    )
                    Spacer(
                        Modifier.height(8.dp)
                    )
                    Text(
                        text = "By ${viewModel.currentRumbleSearchResult?.channel?.name ?: ""}",
                        style = MaterialTheme.typography.titleSmall
                    )
                }
            },
            text = {
                        VideoPlayer(RumbleScraper.create().scrapeVideoSrcFromUrl("https://rumble.com/v1m9oki-our-first-automatic-afk-farms-locals-minecraft-server-smp-ep3-live-stream.html")!!)
            
            },
            confirmButton = {
                TextButton(
                    onClick = {
                        openDialog = false
                    }
                ) {
                    Text("Exit")
                }
            }
        )
    }

运行该代码后,我不断收到NetworkOnMainThread 异常,我尝试了很多方法来修复它,但没有任何效果。

所以我不确定该怎么做才能解决这个问题。我想知道如何在后台等待结果,然后在返回值时在 Compose 函数中显示它?我完全被难住了,任何帮助将不胜感激。

【问题讨论】:

    标签: kotlin android-jetpack-compose kotlin-coroutines


    【解决方案1】:

    你可以这样做:

    var videoSrc by remember { mutableStateOf<String?>(null) }
    
    LaunchedEffect(Unit) {
        withContext(Dispatchers.IO) {
            videoSrc = RumbleScraper.create().scrapeVideoSrcFromUrl("")
        }
    }
    
    text = { VideoPlayer(videoSrc) }
    

    您还可以在 viewModel 中调用 scrapeVideoSrcFromUrl 并更新您将在 UI 中使用的一些状态。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-08-21
      • 2019-01-18
      • 2017-02-03
      • 1970-01-01
      • 2019-12-08
      • 1970-01-01
      • 2018-11-04
      相关资源
      最近更新 更多