Android 在coroutinescope内调用时不执行启动
我在一个协同例程中调用launch,但它不执行。Snackbar操作侦听器正在执行,但由于某些原因启动块未执行Android 在coroutinescope内调用时不执行启动,android,kotlin,kotlin-coroutines,android-snackbar,Android,Kotlin,Kotlin Coroutines,Android Snackbar,我在一个协同例程中调用launch,但它不执行。Snackbar操作侦听器正在执行,但由于某些原因启动块未执行 CoroutineScope(Dispatchers.Main)。启动{ val scope=this val mn=snackbarManager(R.id.root); Snackbar.make(mn.container,R.string.recpt\u已删除,Snackbar.LENGTH\u LONG) .setAction(R.string.undo){ scope.lau
CoroutineScope(Dispatchers.Main)。启动{
val scope=this
val mn=snackbarManager(R.id.root);
Snackbar.make(mn.container,R.string.recpt\u已删除,Snackbar.LENGTH\u LONG)
.setAction(R.string.undo){
scope.launch{**//未执行**
Toast.makeText(requireContext(),“提交”,Toast.LENGTH\u LONG.show())
Log.d(“提交”、“调用提交”)
}
}
.show()
}
在Snackbar action listener中使用的作用域与调用第一个启动
函数时使用的作用域不同。要解决此问题,您可以参考主CoroutineScope
:
val scope = CoroutineScope(Dispatchers.Main)
scope.launch {
// ...
// in action listener:
scope.launch { /*...*/ }
}
或者在Snackbar操作侦听器中使用另一个CoroutineScope
,例如,lifecycleScope
属性:
lifecycleScope.launch {
Toast.makeText(requireContext(),"Committing",Toast.LENGTH_LONG).show()
Log.d("COMMIT", "calling commit")
}
但我认为你的代码有点乱。我认为您应该重新考虑您的方法,不要使用CoroutineScope
来显示Snackbar
更新:
当您在第一个协同程序中初始化范围
变量val scope=this
时,当外部协同程序完成时,此范围
变为已完成。当您在Snackbar
操作侦听器中启动内部协同程序时,范围
已处于完成状态。我们无法使用CoroutineScope
和完成状态启动协同程序。对于第二个范围
启动
您应该使用调度程序。Main
,因为:
Main
coroutine
dispatcher
,仅限于使用UI对象操作的主线程。通常,此类调度程序是单线程的。
第一种方式:
val coro= CoroutineScope(Dispatchers.Main)
coro.launch {
Snackbar.make(requireView(),"milad", Snackbar.LENGTH_LONG)
.setAction("clickMe"){
coro.launch {
Toast.makeText(requireContext(),"Committing", Toast.LENGTH_LONG).show()
Log.d("COMMIT", "calling commit")
}
}.show()
}
然后,您应该将代码更改为:
CoroutineScope(Dispatchers.Main).launch {
Snackbar.make(requireView(),"milad", Snackbar.LENGTH_LONG)
.setAction("clickMe"){
CoroutineScope(Dispatchers.Main).launch {
Toast.makeText(requireContext(),"Committing", Toast.LENGTH_LONG).show()
Log.d("COMMIT", "calling commit")
}
}.show()
}
更新:
val coro= CoroutineScope(Dispatchers.Main)
coro.launch {
Snackbar.make(requireView(),"milad", Snackbar.LENGTH_LONG)
.setAction("clickMe"){
coro.launch {
Toast.makeText(requireContext(),"Committing", Toast.LENGTH_LONG).show()
Log.d("COMMIT", "calling commit")
}
}.show()
}
第二种方式:
val coro= CoroutineScope(Dispatchers.Main)
coro.launch {
Snackbar.make(requireView(),"milad", Snackbar.LENGTH_LONG)
.setAction("clickMe"){
coro.launch {
Toast.makeText(requireContext(),"Committing", Toast.LENGTH_LONG).show()
Log.d("COMMIT", "calling commit")
}
}.show()
}
第一个
CoroutineScope
也使用Dispatchers.Main
,因此这不是问题所在。不,它不使用Dispatchers.Main
,如果使用它,它工作得很好,通过更新我的答案,它将在第二个作用域中再次使用Dispatchers.Main
。@miladsalimi不应该执行launch block,无论使用哪个作用域?我的理解是,无论使用哪个作用域,launch都应该始终执行。我的理解错了吗?