RxJava 主线程总是崩溃

RxJava Main Thread Always Crash

我有两个连续的 API 调用,所以我决定使用 RxJava 平面图来完成它,如下代码,

progress.show(this, "Please Wait ...");

HashMap < String, Object > param = new HashMap < > ();

apiClient.getInstance().OPostponed(api_key, param)
  .subscribeOn(Schedulers.io())
  .observeOn(AndroidSchedulers.mainThread())
  .flatMap(new Function < basicRes, Observable < hodRes >> () {

    @Override
    public Observable < hodRes > apply(basicRes basicRes) throws Throwable {
      HashMap < String, Object > param1 = new HashMap < > ();
      return hodClient.getInstance().hodRUpdateStatus("Bearer " + token, param1);
    }

  }).subscribe(new Observer < hodRes > () {

    @Override
    public void onSubscribe(@NonNull Disposable d) {

    }

    @Override
    public void onNext(@NonNull hodRes hodRes) {
      Log.d(TAG, "onNext: " + hodRes.getData());
      progress.dialog.hide();
      Toast.makeText(OrderAddressDetails.this, hodRes.getData(), Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onError(@NonNull Throwable e) {
      Log.d(TAG, "onError: " + e.getMessage());
      progress.dialog.hide();
      Toast.makeText(OrderAddressDetails.this, "Please Check Internet Connection !", Toast.LENGTH_SHORT).show();

    }

    @Override
    public void onComplete() {

    }
  });

但我的应用总是崩溃,但有以下例外情况,

io.reactivex.rxjava3.exceptions.CompositeException: 2 exceptions occurred. 
        at retrofit2.adapter.rxjava3.CallEnqueueObservable$CallCallback.onFailure(CallEnqueueObservable.java:91)
        at retrofit2.OkHttpCall.callFailure(OkHttpCall.java:175)
        at retrofit2.OkHttpCall.onResponse(OkHttpCall.java:156)
        at okhttp3.RealCall$AsyncCall.execute(RealCall.java:174)
        at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
        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)
      ComposedException 1 :
        com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected a string but was BEGIN_ARRAY at line 1 column 10 path $.data
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:224)
        at retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:39)
        at retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:27)
        at retrofit2.OkHttpCall.parseResponse(OkHttpCall.java:243)
        at retrofit2.OkHttpCall.onResponse(OkHttpCall.java:153)
        at okhttp3.RealCall$AsyncCall.execute(RealCall.java:174)
        at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
        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)
     Caused by: java.lang.IllegalStateException: Expected a string but was BEGIN_ARRAY at line 1 column 10 path $.data
        at com.google.gson.stream.JsonReader.nextString(JsonReader.java:825)
        at com.google.gson.internal.bind.TypeAdapters.read(TypeAdapters.java:401)
        at com.google.gson.internal.bind.TypeAdapters.read(TypeAdapters.java:389)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.read(ReflectiveTypeAdapterFactory.java:129)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:220)
        at retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:39)
        at retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:27)
        at retrofit2.OkHttpCall.parseResponse(OkHttpCall.java:243)
        at retrofit2.OkHttpCall.onResponse(OkHttpCall.java:153)
        at okhttp3.RealCall$AsyncCall.execute(RealCall.java:174)
        at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
        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)
      ComposedException 2 :
        android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
        at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:10750)
        at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:2209)
        at android.view.View.requestLayout(View.java:27055)
        at android.view.View.setFlags(View.java:17525)
        at android.view.View.setVisibility(View.java:12466)
        at com.android.internal.policy.DecorView.setVisibility(DecorView.java:4737)
        at android.app.Dialog.hide(Dialog.java:645)
        at com.mtids.b_d_d.OrderAddressDetails.onError(OrderAddressDetails.java:161)
        at io.reactivex.rxjava3.internal.util.AtomicThrowable.tryTerminateConsumer(AtomicThrowable.java:110)
        at io.reactivex.rxjava3.internal.operators.observable.ObservableFlatMap$MergeObserver.checkTerminate(ObservableFlatMap.java:461)
        at io.reactivex.rxjava3.internal.operators.observable.ObservableFlatMap$MergeObserver.drainLoop(ObservableFlatMap.java:318)
2021-06-07 15:04:43.748 29162-30184/com.mtids.b_d_d E/AndroidRuntime:     at io.reactivex.rxjava3.internal.operators.observable.ObservableFlatMap$MergeObserver.drain(ObservableFlatMap.java:310)
        at io.reactivex.rxjava3.internal.operators.observable.ObservableFlatMap$InnerObserver.onError(ObservableFlatMap.java:536)
        at retrofit2.adapter.rxjava3.BodyObservable$BodyObserver.onError(BodyObservable.java:77)
        at retrofit2.adapter.rxjava3.CallEnqueueObservable$CallCallback.onFailure(CallEnqueueObservable.java:88)
        at retrofit2.OkHttpCall.callFailure(OkHttpCall.java:175)
        at retrofit2.OkHttpCall.onResponse(OkHttpCall.java:156)
        at okhttp3.RealCall$AsyncCall.execute(RealCall.java:174)
        at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
        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)

观察者 onError 方法中出现 progress.dialog.hide() 错误!,我在 logcat 中注意到 Okhttp 日志拦截器 API 都请求 return 成功响应,这是完美的,但我不知道为什么我会收到错误消息!再加上我使用 .observeOn(AndroidSchedulers.mainThread()) 那么为什么我得到 Only the original thread that created a view hierarchy can touch its views. 的第二个异常!?我在这里缺少什么?

任何帮助将不胜感激

编辑:我误解了这个问题。为避免 CalledFromWrongThreadException 尝试将

.observeOn(AndroidSchedulers.mainThread())

之后

.flatMap(new Function < basicRes, Observable < hodRes >> () {

上一个答案:

你的 JSON

出了点问题
Expected a string but was BEGIN_ARRAY at line 1 column 10 path $.data

basicReshodRes 类 不符合 JSON 格式。

顺便说一句。你的代码很难阅读。尽量遵守 Java 惯例。 Class 名称应以大写字母开头。

FlatMap return 是一个新的 Observable 并且您申请了 .observeOn(AndroidSchedulers.mainThread())observable return 上由你的 OPostponed 函数,而不是 observable return 由 flatMap 编辑所以我会说添加 .observeOn(AndroidSchedulers.mainThread()) 在 flatMap

的可观察 return 上
apiClient.getInstance().OPostponed(api_key, param)
  .subscribeOn(Schedulers.io())
  .observeOn(AndroidSchedulers.mainThread())
  .flatMap(new Function < basicRes, Observable < hodRes >> () {

    @Override
    public Observable < hodRes > apply(basicRes basicRes) throws Throwable {
      HashMap < String, Object > param1 = new HashMap < > ();
      return hodClient.getInstance().hodRUpdateStatus("Bearer " + token, param1);
    }

  }).observeOn(AndroidSchedulers.mainThread())
    .subscribeOn(Schedulers.io())
    .subscribe(new Observer < hodRes > () {
        // Rest of your code
   }