问题
New to kotlin, i tried many examples and tutorials to no avail, My requirement is:
- Ui creates a coroutine that initiates a network connection 
- on press of a button, that coroutine sends a msg like "i need info about foo" (taken from a edittext?) to the connected server. 
- 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. 
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.
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?
Update:Code
// 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 :(
Answer: I used Fragments with ViewModels and coroutine launched via viewmodelScope, working flawlessly so far.
回答1:
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 is an extension property available inside the coroutine via the CoroutineScope object.
When the screen is rotated, the connection is closed and a new one is being opened once the coroutine is called again in onCreate.
来源:https://stackoverflow.com/questions/57717328/kotlin-coroutines-continues-updates