标签: kotlin-coroutines

Kotlin Android - 分派到主线程的正确方法

我正在使用 OkHttp 库从互联网下载一些数据,然后androidx.lifecycle.ViewModel 我想更新我的LiveData. 似乎从后台线程执行此操作会引发异常,如下所示:

2022-01-17 15:47:59.589 7354-7396/com.example.myapplication E/AndroidRuntime: FATAL EXCEPTION: OkHttp Dispatcher
    Process: com.example.myapplication, PID: 7354
    java.lang.IllegalStateException: Cannot invoke setValue on a background thread
        at androidx.lifecycle.LiveData.assertMainThread(LiveData.java:487)
        at androidx.lifecycle.LiveData.setValue(LiveData.java:306)
        at androidx.lifecycle.MutableLiveData.setValue(MutableLiveData.java:50)
        at com.example.myapplication.MainActivityViewModel$getOneMoreCat$1.invoke(MainActivityViewModel.kt:86)
        at com.example.myapplication.MainActivityViewModel$getOneMoreCat$1.invoke(MainActivityViewModel.kt:39)
        at com.example.myapplication.singleton.CommunicationManager$sendRequest$1.onResponse(CommunicationManager.kt:24)
        at okhttp3.internal.connection.RealCall$AsyncCall.run(RealCall.kt:519)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
        at java.lang.Thread.run(Thread.java:923)
Run Code Online (Sandbox Code Playgroud)

现在我找到了两种不同的方法来调度到主线程ViewModel(根据 AAC 指南,它没有引用 Context),请参见此处:

            GlobalScope.launch {
                withContext(Dispatchers.Main) {
                    // do whatever, e.g. update LiveData
                }
            }
Run Code Online (Sandbox Code Playgroud)

或者

            Handler(Looper.getMainLooper()).post(Runnable {
                   // do whatever, e.g. update LiveData
            })
Run Code Online (Sandbox Code Playgroud)

哪个是正确的方法?也就是说,在运行时影响最小。

更新我确实发现我也可以这样做myLiveData.post() …

android kotlin android-livedata kotlin-coroutines coroutinescope

0
推荐指数
1
解决办法
5838
查看次数

如何从构建的流对象中发出值

我的问题是我们如何从构建的流对象中发出一个值,如下所示:

class Sample {
    var flow: Flow<Object> = null

    fun sendRequest(){
       flow = flow{}
       requestWrapper.flowResponse = flow

    }

    fun getResponse(){
       // I want to emit data here with built flow object on 
       // requestWrapper like this

        requestWrapper.flowResponse.emit()

    }
}
Run Code Online (Sandbox Code Playgroud)

这个问题有什么可能的解决方案吗?

android kotlin kotlin-coroutines kotlin-flow kotlin-sharedflow

0
推荐指数
1
解决办法
627
查看次数

Kotlin Android 中的 runOnUiThread 和 CoroutineScope(Dispatchers.Main) 有什么区别

我不知道CoroutineScope(Dispatchers.Main).launchrunOnUiThread之间有什么区别,我认为两者都会在主线程上运行。

但仍然很混乱,有什么区别吗?

谢谢。

multithreading android kotlin android-runonuithread kotlin-coroutines

0
推荐指数
1
解决办法
2092
查看次数

为什么 GlobalScope.async 似乎比 coroutineScope.async 性能更高

我目前正在开发小型应用程序来学习 Kotlin(使用一些 Spring Boot 功能来加快工作速度)。不幸的是,我无法理解异步运行的协程返回一些结果,这很可能是由于对协程作用域的理解不好。

以下代码是我的“主要”方法

@Component
class GameRunner() : CommandLineRunner {

    override fun run(vararg args: String) = runBlocking {

        val players = listOf(Player(1),Player(2),Player(3),Player(4))
        val results = mutableListOf<Results>()
        val measureTimeMillis = measureTimeMillis {
            val deferredResults = mutableListOf<Deferred<List<Results>>>()
            for (i in 0 until 250) {
                deferredResults.add(async { executeLadderRound(players.shuffled()) })
            }
            results.addAll(deferredResults.awaitAll().flatten())
        }
        // ... present the results ...
    }
    
    // for the record, this method plays a simulation of a board game that is fully blocking CPU intensive process, there are …
Run Code Online (Sandbox Code Playgroud)

kotlin kotlin-coroutines

0
推荐指数
1
解决办法
150
查看次数