首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何从非挂起的回调函数从LiveData构建器发出

如何从非挂起的回调函数从LiveData构建器发出
EN

Stack Overflow用户
提问于 2019-11-17 06:25:37
回答 1查看 348关注 0票数 0

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

代码语言:javascript
复制
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
}

}

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-11-17 06:42:22

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

我还在讨论Cronet integration with LiveData and Kotlin CoroutinesMedium article中捕获了我的学习。

代码语言:javascript
复制
override suspend fun getLiveData(): LiveData<List<MyItem>> = liveData(coroutineDispatcher) {

    lateinit var result: List<MyItem>
    suspendCoroutine<List<MyItem>> { continuation ->

        val requestBuilder = cronetEngine.newUrlRequestBuilder(
            "http://www.exampleApi.com/example",
            object : UrlRequest.Callback() {

                // other callbacks not shown

                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)
                        result = myItems
                        continuation.resume(result)
                    }
                    byteBuffer?.clear()
                    request?.read(byteBuffer)
                },
                executor
        )
        val request: UrlRequest = requestBuilder.build()
        request.start()

    }
    emit(result)
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58895770

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档