如何在可组合的乐趣中在协程上显示敬酒消息?

问题描述 投票:0回答:3

首先,我的英语不好。对不起

我想像下面这样展示祝酒消息

但它不起作用。

'this' 应该是上下文,但它总是 CoroutineScope

LocalContext.current 不工作

这是不好的做法吗?如果是,请解释并给我好的答案!

@Composable
fun DogButton() {

    androidx.compose.material.Button(onClick = {

        CoroutineScope(Dispatchers.Main).launch {

            try {

                val response = ApiAdapter.apiClient.getRandomDogImage()

                if (response.isSuccessful && response.body() != null) {

                } else {

                    Toast.makeText(this, "Error", Toast.LENGTH_SHORT) // it occur compile error. 


                }

            } catch (exception : Exception) {


            }
        }

    /*TODO*/ }) {

        Text(text = "Get a Dog Image")
    }
}

希望一切顺利

android kotlin coroutine
3个回答
1
投票

您无法从协程中获取 LocalContext,因为协程

launch
块不是可组合项。在声明 Button 之前使用它,并确保应用程序 Context 是安全的,因为您在协程中使用的 context 可能比可组合项的寿命长。

@Composable
fun DogButton() {
    val appContext = LocalContext.applicationContext

    androidx.compose.material.Button(onClick = {
        //...
        Toast.makeText(appContext, ...

出于代码组织的目的,在 ViewModel 或其他类似类中进行此类工作可能更合适。您可以使用 AndroidViewModel 并使用其应用程序引用来获取上下文。那么这个点击监听只需要调用ViewModel函数即可

此代码:

CoroutineScope(Dispatchers.Main).launch {

通常是一种反模式,无论您是否在可组合项中。这意味着您正在创建一个不受限制的协程——无论您的应用程序的关联部分是否已经消失和销毁,它都会一直存在直到完成,因此它是内存泄漏和其他资源浪费的来源。

通常,您总是使用具有适当生命周期的适当 CoroutineScope 启动协程。当您从中启动的工作已过时时将被取消。

您的代码可能是个例外,因为它根本不与可组合项或 Activity UI 交互。它只启动一个 Toast,这是应用程序范围内的一个 UI。所以如果你真的想在 Activity 关闭的情况下显示这个 Toast,那么以这种方式启动你的协程就可以了。

我认为在这种情况下,您应该使用 GlobalScope 来清楚地表明这是一个不属于可能取消它的生命周期的协程。它实际上是一样的,但你不会创建一个冗余的 CoroutineScope。


0
投票

Composable
函数不应用于调用 API 或执行任何处理密集型工作。 (Source)您调用 API 并在失败时显示 Toast 的要求可以在
ViewModel
和该按钮的相应
onClick
内处理。


0
投票

要在 Composable 函数内的协程范围内显示 toast,您可以使用 CoroutineScope.launch 函数和 CoroutineExceptionHandler 来捕获协程中发生的任何异常。

举个例子:

fun MyComposableFunction() {
val coroutineScope = rememberCoroutineScope()

Button(onClick = {
    coroutineScope.launch(CoroutineExceptionHandler { _, throwable ->
        // handle exception, e.g. log or display error message
        Toast.makeText(LocalContext.current, "An error occurred: ${throwable.message}", Toast.LENGTH_SHORT).show()
    }) {
        // run your coroutine code here
        launch {
            // your coroutine code here
            Toast.makeText(LocalContext.current, "Toast message", Toast.LENGTH_SHORT).show()
        }
    }
}) {
    Text("Show Toast")
}

} 在这个例子中,我们首先通过调用 rememberCoroutineScope() 获得一个 CoroutineScope。然后我们使用这个范围在点击按钮时启动一个新的协程。我们传入一个 CoroutineExceptionHandler 来捕获协程中发生的任何异常。在启动块内,我们可以运行协程代码,在本例中,它使用 Toast.makeText 函数显示 Toast 消息。请注意,我们使用 LocalContext.current 来获取用于显示 Toast 消息的当前上下文。

这只是一个示例,说明如何在可组合函数的协程范围内显示 Toast 消息。在 Compose 中有很多方法可以处理协程和异常,因此请务必选择最适合您的用例的方法。

© www.soinside.com 2019 - 2024. All rights reserved.