在协同程序中等待侦听器内的数据

JPM*_*JPM 7 android kotlin kotlinx.coroutines

我有一个协程我想在启动页面启动android启动时.在开始下一个活动之前,我想等待数据回来.做这个的最好方式是什么?目前我们的android正在使用0.26.0的实验协程......暂时还不能改变它.

更新:我们现在使用最新的协同程序,不再进行实验

onResume() {
    loadData()
}

fun loadData() = GlobalScope.launch {
    val job = GlobalScope.async {
        startLibraryCall()
    }
    // TODO await on success
    job.await()
    startActivity(startnewIntent)
}

fun startLibraryCall() {
    val thirdPartyLib() = ThirdPartyLibrary()
    thirdPartyLib.setOnDataListener() { 
        ///psuedocode for success/ fail listeners
        onSuccess -> ///TODO return data
        onFail -> /// TODO return other data
    }
}
Run Code Online (Sandbox Code Playgroud)

Eri*_*ori 11

第一点是我将loadData函数更改为挂起函数而不是使用launch.最好选择在调用站点定义如何继续执行.例如,在实施测试时,您可能希望在一个内部调用您的协同程序runBlocking.您还应该正确实现结构化并发而不是依赖GlobalScope.

在问题的另一方面,我将实现一个扩展函数ThirdPartyLibrary,将其异步调用转换为挂起函数.这样,您将确保调用协程实际上等待库调用具有一些值.

由于我们建立loadData了暂停功能,现在我们可以确保它只在ThirdPartyLibrary呼叫结束时启动新活动.

import kotlinx.coroutines.*
import kotlin.coroutines.*

class InitialActivity : AppCompatActivity(), CoroutineScope {
    private lateinit var masterJob: Job
    override val coroutineContext: CoroutineContext
        get() = Dispatchers.Main + masterJob

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        masterJob = Job()
    }

    override fun onDestroy() {
        super.onDestroy()
        masterJob.cancel()
    }

    override fun onResume() {
        this.launch {
            val data = ThirdPartyLibrary().suspendLoadData()
            // TODO: act on data!
            startActivity(startNewIntent)
        }
    }
}

suspend fun ThirdPartyLibrary.suspendLoadData(): Data = suspendCoroutine { cont ->
    setOnDataListener(
            onSuccess = { cont.resume(it) },
            onFail = { cont.resumeWithException(it) }
    )
    startLoadingData()
}
Run Code Online (Sandbox Code Playgroud)