【问题标题】:Retrofit - android.os.NetworkOnMainThreadException with RxKotlin改造 - 带有 RxKotlin 的 android.os.NetworkOnMainThreadException
【发布时间】:2020-03-06 19:38:43
【问题描述】:

我创建了 rx 函数来从 android 中的view-model 调用网络调用,它在主线程函数上解析网络。

我只是更改了几行代码就可以了。但我需要知道原因,因为它使用相同的构建器模式来创建rx-call。 一旦我尝试在 flatmap 调用后更改 .doOnSubscribe()doOnComplete ().applySchedulers() ,它是否有效?这是怎么回事?

fun loadjobs(var countryID:String){
subscription.add(
repository.getMainJobsFromLocal(countryID)
          .doOnSubscribe { postProgress(StatusModel(Status.IN_PROGRESS))}
          .doOnComplete { postProgress(StatusModel(Status.COMPLETED)) }
          .applySchedulers()
          .flatMap {
           if (it.isNullOrEmpty()) {
              repository.getMainJobsFromServer(countryID)
           } else {
              Flowable.just(Response.success(it))
           }
          }
          .subscribe({
            if (it.isResponseOk()) {
             postProgress(StatusModel(Status.SUCCESS))
             mainJobResponse.postValue(it.body())
           } else {
             postProgress(StatusModel(Status.FAILED))
             mainJobResponse.postValue(null)
           }
          }, {
           postProgress(StatusModel(Status.FAILED))
           mainJobResponse.postValue(null)
        }))
}


fun loadjobs(var countryID){
subscription.add(
repository.getMainJobsFromLocal(countryID)
          .flatMap {
           if (it.isNullOrEmpty()) {
             repository.getMainJobsFromServer(countryID).flatMap {
               Flowable.just(it)
             }
           } else {
             Flowable.just(Response.success(it))
           }
          }.doOnSubscribe { postProgress(StatusModel(Status.IN_PROGRESS)) }
            .doOnComplete { postProgress(StatusModel(Status.COMPLETED)) }
            .applySchedulers()
            .subscribe({
              if (it.isResponseOk()) {
                postProgress(StatusModel(Status.SUCCESS))
                mainJobResponse.postValue(it.body())
               } else {
               postProgress(StatusModel(Status.FAILED))
               mainJobResponse.postValue(null)
              }
           }, {
            postProgress(StatusModel(Status.FAILED))
            mainJobResponse.postValue(null)
    }))
}

【问题讨论】:

  • applyScheduler() 不会使整个可观察流变为异步。每次调用网络请求时,都应使用此函数将其链接起来。
  • 告诉我哪些函数应该在另一个线程中异步?

标签: android android-viewmodel flatmap rx-kotlin


【解决方案1】:

subscribeOn(Schedulers.io())observeOn(AndroidSchedulers.mainThread()) 添加到您的 Observable。

【讨论】:

  • 这两个是带有 .applyScheduler() 的集合,它是一个扩展函数。 fun Flowable.applySchedulers(): Flowable { return subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()) }
【解决方案2】:

applySchedulers() 在 flatmap 调用之后它起作用了吗?这是怎么回事?

observeOn() 影响下游的一切。如果您在observeOn() 之后有一个flatMap(),它将在该调度程序上执行。

同样subscribeOn()影响上游链。

出于这些原因,对于大多数用例,您希望将调度程序应用在 rx 链的末端而不是中间。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-02-09
    • 2015-02-13
    • 1970-01-01
    • 2018-02-27
    • 1970-01-01
    • 1970-01-01
    • 2015-06-16
    • 2016-02-08
    相关资源
    最近更新 更多