首先,我的英语不好,很抱歉
我想显示一个像下面这样的吐司词
但它不工作。
'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")
}
}
我希望它会很好
2条答案
按热度按时间daupos2t1#
你不能从你的协程中获取LocalContext,因为协程
launch
块不是Composable。在声明你的Button之前使用它,并获取应用程序Context以确保安全,因为你正在一个可能比Composable更持久的协程中使用上下文。出于代码组织的目的,在ViewModel或其他类似的类中进行此类工作可能更合适。您可以使用AndroidViewModel并使用其Application引用来获取Context。然后此单击侦听器只需调用ViewModel函数。
此代码:
通常是一个反模式,不管你是否在Composable中。这意味着你正在创建一个无限制的协程--它将一直存在到完成,不管你的应用程序的相关部分是否已经消失或被破坏,因此它是内存泄漏和其他浪费资源的来源。
通常,您总是使用具有适当生命周期的适当CoroutineScope启动协程。当您从其中启动的工作过时时,该生命周期将被取消。
你的代码可能是一个例外,因为它根本没有与可组合或Activity UI交互。它只启动吐司,这是应用程序范围内的UI。所以如果你真的想在Activity关闭时显示这个Toast,那么以这种方式启动你的协程是可以的。
我的观点是,在这种情况下,你应该使用GlobalScope来清楚地表明这是一个协同程序,它不是可能取消它的生命周期的一部分。它实际上是相同的,但你不会创建一个冗余的CoroutineScope。
ffx8fchx2#
Composable
函数不应用于调用API或执行任何处理密集型工作。(来源)您调用API和在失败时显示吐司的需求可以在ViewModel
和该按钮的相应onClick
中处理。