androidkotlinkotlin-coroutinescoroutinecoroutinescope

Kotlin coroutines, is there a better way to return this value?


Struggling with coroutines, but is there a better way to use/get the value for a long running call out here before passing it onto another network coroutine with the callback? I've seen others but than i can't seem to use the value with the latest droid coroutine release, like I can't seem make this work Kotlin Coroutines with returning value

private suspend fun launchGeneratePayload(): String? { 
    return withContext (Dispatchers.Default) {
        try {
            val payloadString = slowStringGeneration()//Slow
            return@withContext payloadString
        } catch (e: java.lang.Exception) {
            return@withContext null
        }
    }
}

Where the value is ultimately used

public someFunction(callback: CallBack) {      
    val params: JSONObject = JSONObject()
    params.put("param1", "param1Value")
    runBlocking{ //probably should be launch or similar
        val payload = launchGeneratePayload()
        params.put("param2", payload)
        //call network function with params & callback
        //networkCall (
    } 
}

Thanks for any help

edit: I think was actually looking for was just a bit different with

suspend fun launchGeneratePayload(): String? =
    withContext(Dispatchers.Default) {
        try {
            slowStringGeneration() //slow
        } catch (e: java.lang.Exception) {
             null
        }
    }
}

Will add as an answer later incase i'm still off on this/else.


Solution

  • You can use launch coroutine builder to start the coroutine:

    private var job: Job = Job()
    private var scope = CoroutineScope(Dispatchers.Main + job)
    
    fun someFunction(callback: CallBack) {
        val params: JSONObject = JSONObject()
        params.put("param1", "param1Value")
        scope.launch { // launch the coroutine
            val payload = generatePayload() // generate String without blocking the main thread
            params.put("param2", payload)
            //call network function with params & callback
            //networkCall (params, callback)
        }
    }
    
    suspend fun generatePayload(): String? = withContext(Dispatchers.Default) {
        try {
            slowStringGeneration() //slow
        } catch (e: java.lang.Exception) {
            null
        } 
    }
    

    Note: you can also make networkCall() as suspend, then you won't need to use callback.

    To use Dispatchers.Main in Android add dependency to the app's build.gradle file

    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.0.1'