如何从非暂停回调函数从LiveData构建器发出

时间:2019-11-16 22:25:37

标签: kotlin android-livedata coroutine kotlin-coroutines cronet

我是LiveData和Kotlin Coroutines的新手。我正在尝试使用Chromium Cronet库从我的存储库类发出请求以返回LiveData对象。要返回liveData,我使用了新的LiveData构建器(coroutines with LiveData)。成功的Cronet请求将如何发出结果?

class CustomRepository @Inject constructor(private val context: Context, private val gson: Gson) : Repository {
    private val coroutineDispatcher = Executors.newSingleThreadExecutor().asCoroutineDispatcher()

    override suspend fun getLiveData(): LiveData<List<MyItem>> = liveData(coroutineDispatcher) {
        val executor = Executors.newSingleThreadExecutor()
        val cronetEngineBuilder = CronetEngine.Builder(context)
        val cronetEngine = cronetEngineBuilder.build()
        val requestBuilder = cronetEngine.newUrlRequestBuilder(
            "http://www.exampleApi.com/example",
            CustomRequestCallback(gson),
            executor
        )
        val request: UrlRequest = requestBuilder.build()
        request.start()
    }

    class CustomRequestCallback(private val gson: Gson) : UrlRequest.Callback() {

        override fun onReadCompleted(request: UrlRequest?, info: UrlResponseInfo?, byteBuffer: ByteBuffer?) {
            byteBuffer?.flip()
            byteBuffer?.let {
                val byteArray = ByteArray(it.remaining())
                it.get(byteArray)
                String(byteArray, Charset.forName("UTF-8"))
            }.apply {
                val myItems = gson.fromJson(this, MyItem::class.java)
                // THIS IS WHAT I WANT TO EMIT
                // emit(myItems) doesn't work since I'm not in a suspending function
            }
            byteBuffer?.clear()
            request?.read(byteBuffer)
        }

        // other callbacks not shown
}

}

1 个答案:

答案 0 :(得分:0)

该解决方案涉及将4传统回调结构包装在UrlRequest.Callback构建器中。

我还通过讨论Medium articleCronet integration with LiveData and Kotlin Coroutines捕捉了自己的学习经验。

suspendCoroutine