android - 在 doAsync 结果中调用方法 - 主线程上的工作太多

标签 android kotlin rx-java anko

这是我做一些后台工作的代码

 fun getAllArtists(): LiveData<List<Artist>> {
    val artistListLiveData = MutableLiveData<List<Artist>>()
    doAsync {
        val artistList = MusicGenerator.getAllArtists()
        onComplete {
            getArtistInfo(artistList)
            artistListLiveData.value = artistList
        }
    }
    return artistListLiveData
}

完成后,我进行网络调用以获取艺术家信息

private fun getArtistInfo(artistList: List<Artist>) {

    artistList.forEach {

        val url = "http://ws.audioscrobbler.com/2.0/?method=artist.getinfo&api_key=API_KEY&format=json"
                .plus("&artist=")
                .plus(it.artistName)

        val artistInfoList: MutableList<ArtistInfo> = ArrayList()

        apiService.getArtistImage(url)
                .observeOn(AndroidSchedulers.mainThread())
                .subscribeOn(Schedulers.io())
                .subscribe({ result ->
                    info { result.toString() }
                }, { error ->
                    error.printStackTrace()
                })

        verbose { artistInfoList.size }
    }
}

但是,我要确保网络调用在后台线程中进行,而结果在主线程中进行。

但是 UI 中存在卡顿,并且 logcat 显示在主线程上完成了太多工作。我不明白,我在这里做错了什么?

最佳答案

我怀疑您创建了太多线程。 io() 是无界的,计算 是基于处理器内核的。由于您正在执行 io,因此您应该使用 io(),但还需要注意不要同时发出大量请求。您可以使用 Flowable.flatMap 代替 foreach 来遍历您的列表。这里的关键是给flatMap指定一个最大并发值。下面,我将其设置为 4,但您可以尝试使用该数字,看看是什么在不造成卡顿的情况下为最大请求数提供了良好的结果。此外,由于我们使用的是 flatMap,因此我将您的 subscribe 移到了循环之外,以处理来自 getArtistImage 的结果流。目前尚不清楚您在使用代码 fragment 中的 artistInfoList 做什么,因此我将其关闭,但您可以使用以下内容作为指南 -

private fun getArtistInfo(artistList: List<Artist>) {

    Flowable.fromIterable(artistList).flatMap({
        val url = "http://ws.audioscrobbler.com/2.0/?method=artist.getinfo&api_key=API_KEY&format=json"
                .plus("&artist=")
                .plus(it.artistName)

        getArtistImage(url)
                .subscribeOn(Schedulers.io())
    }, 4)
            .subscribe({ result ->
                info { result.toString() }
            }, { error ->
                error.printStackTrace()
            })
}

关于android - 在 doAsync 结果中调用方法 - 主线程上的工作太多,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49720325/

相关文章:

java - 为什么多个 RXJava Observables 没有发生并行执行?

rx-java - RxJava 在与单元测试相同的线程上订阅和观察

android - 如何使用 RxJava 处理回收站 View 的项目点击

java - 使用反射查找 JNI 中的 Java 类是否为 Final

android - Fragment 将所有导航控制委托(delegate)给 Activity 是个好主意吗?

android - R算作android依赖吗?

android - 如何在 kotlin @Parcelize 中使用 null

json - 将 JSONArray 转换为 Iterable<JSONObject> - Kotlin

android - Eclipse 不会创建新的 Android Activity 源或布局。尝试过更新和 sdk

java - 为什么 getEdgeFlags() 总是返回 0