Rishab Parmar
Rishab Parmar

Reputation: 419

Kotlin Coroutine not waiting for the network result to return

I am trying to get some data from the server in Kotlin, upon which I wish to do some further process, like displaying it to the user. But the execution is not waiting/ blocking for the result to return and is carrying on with the execution.

Here is the code:

class UserLand : AppCompatActivity() {

class SyncViewModel(): ViewModel() {
        suspend fun startingSync(accesstoken: String): String {
            var response = ""
            viewModelScope.launch(Dispatchers.IO) {
                val reqParam = "token=$accesstoken"
                val mURL = URL("<-- server end point here -->")

                with(mURL.openConnection() as HttpURLConnection) {
                    // optional default is GET
                    requestMethod = "POST"

                    val wr = OutputStreamWriter(outputStream);
                    wr.write(reqParam);
                    wr.flush();

                    println("2 : $url")
                    println("3 : $responseCode")

                    BufferedReader(InputStreamReader(inputStream)).use {

                        var inputLine = it.readLine()
                        while (inputLine != null) {
                            response += inputLine
                            inputLine = it.readLine()
                        }
                        Log.d("4: ","Response : $response")
                    }
                }
            }
            Log.d("5", response)
            return response
        }
    }

 fun syncWithServer(view: View) {           
        val accesstoken = "johndoe"
        var response = ""
        if (accesstoken != null) {
            Log.d("----->", "1")
            runBlocking {
                response = SyncViewModel().startingSync(accesstoken)                
                Log.d("----->", "6")
            }
        }
        // 
        Log.d("Final result: 7:---------> ", response)

    }

 override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_snyc_packages_with_server)      
    }    
}

I'm calling syncWithServer() from a button click on the screen. After this, the syncWithServer() will start a network request on a separate thread in the function startingSync(). Now the order of execution of the logs that I am aiming for is as follows:

1->2->3->4->5->6->7 (according to the logs and print messages). Finally, at log(7), I will get the response from the server which I want to process further. But the actual execution comes out to be as follows:

1->6->2->3->4. Note that 5 and 7 are not logged in android logcats. I believe that the execution thread is not waiting for the network request result to return and hence the ideal steps of execution are not being achieved.

I am just starting out with co-routines in kotlin. I know I am missing something out but what is it exactly?

Upvotes: 2

Views: 1697

Answers (1)

i30mb1
i30mb1

Reputation: 4776

viewModelScope.launch(Dispatchers.IO) in your code create parallel work, you have 2 variants to fix it :

1 - instead of viewModelScope.launch(Dispatchers.IO) use withContenxt(Dispatchers.IO) that will only change the dispathers

2 - instead of viewModelScope.launch(Dispatchers.IO) use viewModelScope.async(Dispatchers.IO) and wait it result by calling the .await() end of this block

Upvotes: 2

Related Questions