如何使用协程启动真正的异步函数
我正在学习Kotlin Coroutines。我有一个情况,当用户单击登录按钮时,我想执行一些登录工作。我不希望它阻止该应用程序,它将显示一个进度旋转器,直到登录活动完成,但是用户应该可以自由移动和UI更新(实际上我想在Progess Spinner上发短信根据舞台更新)。
但是,似乎可以启动coroutine的唯一方法是来自Runblocking
元素,这实际上使异步性质无效。
我的用例:
binding.loginSignIn.setOnClickListener{ signIn(it) }
单击登录时,将登录此功能,
private fun signIn(view : View) {
// Do some data validation
if (!isValidEmail(model.email.value)) {
app.messenger.showSnackBar(R.string.login_enter_email, view, Messenger.TYPE_WARNING)
return
}
if (model.pwd.value == null || model.pwd.value!!.isEmpty()) {
app.messenger.showSnackBar(R.string.login_enter_pwd, view, Messenger.TYPE_WARNING)
return
}
// Show the progress spinner
model.showProgress.value = true
runBlocking {
launch(Dispatchers.Default) {
try {
// Talk to server, talk to data storage and synchronise some data
} catch (e: ServerException) {
app.messenger.showSnackBar(e.message, view, Messenger.TYPE_WARNING)
} catch (e: Exception) {
app.messenger.showSnackBar(e.message, view, Messenger.TYPE_WARNING)
}finally{
// allows to call a function like a 'callback' ?
}
}
}
// This now waits until the coroutine above completes
我不希望此功能等待。我希望OnClick事件结束并返回控制。
我想要的是为Coroutine提供一个回调功能,一旦Coroutine完成,该功能将执行。我什至可以在终于在
块上打电话给我自己,我认为我认为会导致相同的行为。
这是基本async
等待
键入行为,但是我从文档中找不到如何在等待Coroutine结束的同时脱离运行模块?
我已经查看了globalscope.launch
,但这是关于在完成或错误时不警报的警告,这不是我想要的。
如果我尝试简单地使用启动
它必须在Coroutine范围内,因此从我可以看到的runblocking看来,似乎是Coroutines的唯一允许的外层。显然,我从根本上误解了有关Coroutines如何工作 /他们的目的,有人可以解释吗?
I am learning Kotlin coroutines. I have a situation where I want to execute some sign-in stuff when a user clicks a sign-in button. I don't want this to block the app, it will display a progress spinner until the sign-in activity is complete but the user should be free to move around and the UI update (in fact I'd like text on the progess spinner to update depending on the stage).
However, the only way it seems possible to launch a coroutine is from within a runBlocking
element, which essentially invalidates the asynchronous nature.
My use case:
binding.loginSignIn.setOnClickListener{ signIn(it) }
On sign in click, exectute this function
private fun signIn(view : View) {
// Do some data validation
if (!isValidEmail(model.email.value)) {
app.messenger.showSnackBar(R.string.login_enter_email, view, Messenger.TYPE_WARNING)
return
}
if (model.pwd.value == null || model.pwd.value!!.isEmpty()) {
app.messenger.showSnackBar(R.string.login_enter_pwd, view, Messenger.TYPE_WARNING)
return
}
// Show the progress spinner
model.showProgress.value = true
runBlocking {
launch(Dispatchers.Default) {
try {
// Talk to server, talk to data storage and synchronise some data
} catch (e: ServerException) {
app.messenger.showSnackBar(e.message, view, Messenger.TYPE_WARNING)
} catch (e: Exception) {
app.messenger.showSnackBar(e.message, view, Messenger.TYPE_WARNING)
}finally{
// allows to call a function like a 'callback' ?
}
}
}
// This now waits until the coroutine above completes
I don't want this function to wait. I want the onClick event to end and return control.
What I want is to give the coroutine a callback function, that executes once the coroutine has completed. I could even call one myself in the finally
block above that I assume would result in the same sort of behaviour.
This is basic async
await
type behaviour but I can't figure out from the documentation how to break out of the runBlocking while awaiting the end of the coroutine?
I have looked at GlobalScope.launch
but that is riven with warnings about not alerting when complete or errors - which is not what I want.
If I try to simply use launch
it has to be within a coroutine scope already, so from what I can see runBlocking seems to be the only allowable outer layer for coroutines. I am clearly fundamentally misunderstanding something about how coroutines work / what they're for, can someone please explain?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
几个小时的寻找,提出一个问题,五分钟后找到答案。
答案似乎是
LifecycleScope.launch{}
仍然不确定回调,但添加一个函数调用到
finally
似乎可以完成这项工作请有人添加一个回答是否有更好的方法来处理这个问题。所以我最终得到:
在答案中添加了 @CommonsWare 提供的链接:
https://developer.android.com/topic/libraries/architecture/coroutines
Hours of looking, ask a question, and five minutes later find an answer.
The answer appears to be
LifecycleScope.launch{}
Still not sure about the callback, but adding a function call to
finally
seems to do the job please someone add an answer if there is a better way of handling this.So I have ended up with:
Added link provided by @CommonsWare to the answer:
https://developer.android.com/topic/libraries/architecture/coroutines