Kotlin协程,继续更新 [英] Kotlin coroutines, continues updates

查看:870
本文介绍了Kotlin协程,继续更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

kotlin的新手,我尝试了许多示例和教程,但都无济于事, 我的要求是:

New to kotlin, i tried many examples and tutorials to no avail, My requirement is:

  • Ui创建一个协程以启动网络连接

  • Ui creates a coroutine that initiates a network connection

只要按一下按钮,协同程序就会向连接的服务器发送一个消息,例如我需要有关foo的信息"(来自edittext?).

on press of a button, that coroutine sends a msg like "i need info about foo" (taken from a edittext?) to the connected server.

协程还应该侦听传入的消息,并将这些消息传递给ui(或直接更新ui)

coroutine should also be listening for incoming messages and pass those messages to ui (or update ui directly)

协程应保持与服务器的连接,除非被告知要关闭连接.

coroutine should keep connected to the server unless it is told to close the connection.

我觉得我需要全局作用域dispatcher.io.

I feel that i need global scope, dispatcher.io.

我发现的所有示例只不过是打印值和终止协程而已,并且没有提及如何实现长期运行的协程,而协程可以用作持续的后台套接字连接.

All the examples i found do nothing more than printing values and terminating coroutines and doesn't mention how to implement a long running coroutine which can act as a continues background socket connection.

我确实知道,通过循环监听套接字可以实现这一点,但是我在这里需要哪种协程以及如何向ui发送消息或从ui发送消息?

I do understand that listening from a socket in loop can achieve that but what kind of coroutine do i need here and how do i send messages to and from ui?

更新:代码

// Added comments for new devs who love copy-pasting as it is a nice little startup code
// you can add android:screenOrientation="portrait" in manifest if you want to use this code
class MainActivity2 : AppCompatActivity(), CoroutineScope {
override val coroutineContext: CoroutineContext
    get() = Dispatchers.Main + job

private lateinit var job: Job // lateinit = will be initialized later 

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main2)
    job = Job() // initialized 
    launch(Dispatchers.IO) { //dispatcher defined, otherwise launch{
        // activity also extends coroutine scope so it will be launched in that scope
        connector()
    }
}

override fun onDestroy() {
    // to avoid launching multiple coroutines
    // on configuration changes and cancelling it on exit
    job.cancel() 
    super.onDestroy()
}

suspend fun connector() = withContext(Dispatchers.IO){ //defined dispatcher twice here
// useless, once is enough, either here or on launch
//if you defined dispatcher on launch, fun should look like
// suspend fun connector(){
    while(true){
        // talk to a server
        // need to update ui? 
        withContext(Dispatchers.Main){ // back to UI
            // you can update/modify ui here
            Toast.makeText(this@MainActivity2, "hi there", Toast.LENGTH_LONG).show()
        }
    }
}

}

新问题:我如何处理配置更改:(

New Question: How do i handle configuration changes :(

答案:我将Fragments与ViewModels一起使用,并通过viewmodelScope启动了协程,到目前为止,它都可以正常工作.

推荐答案

根据我的理解,您想创建一个协程,以侦听连接上的响应.在这种情况下,您唯一需要确保的是,一旦活动结束,协程应该是可取消的.

From what I understand you want to create a coroutine that listens for responses over a connection. In that case the only thing that you need make sure is that the coroutine should be cancellable, once activity is closed.

suspend fun connector() = withContext(Dispatchers.IO){
    try {
        // open the connection here
        while(isActive) {
        var doing  : String = "nothing" // fetched from a network call
              withContext(Dispatchers.Main){
                Toast.makeText(this@MainActivity2, doing, Toast.LENGTH_LONG).show()
            }
        }
    } finally {
        withContext(NonCancellable) {
            //close the connection here     
        }   
    }

isActive是在协程内部通过CoroutineScope对象提供的扩展属性.

isActive is an extension property available inside the coroutine via the CoroutineScope object.

旋转屏幕时,一旦在onCreate中再次调用协程,则连接将关闭并打开新的连接.

When the screen is rotated, the connection is closed and a new one is being opened once the coroutine is called again in onCreate.

这篇关于Kotlin协程,继续更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆