android– 在我更新到Retrofit 2.0之后,在不同的线程中发布了对onNext的onNext调用

android– 在我更新到Retrofit 2.0之后,在不同的线程中发布了对onNext的onNext调用,第1张

概述在我们使用Retrofit1.9时,我的同事创建了以下课程publicclassSomeApiCallAction{privateSubscriptionsubscription;privateNoInternetConnectionInterfacenoInternetConnectionInterface;publicinterfaceNoInternetConnectionInterface{PublishSubj

在我们使用Retrofit 1.9时,我的同事创建了以下课程

public class SomeAPICallAction {  private Subscription subscription;  private NoInternetConnectionInterface noInternetConnectionInterface;  public interface NoInternetConnectionInterface {      PublishSubject<Integer> noInternetConnection(Throwable throwable);  }  public voID execute(Subscriber subscriber, NoInternetConnectionInterface noInternetConnectionInterface) {      this.noInternetConnectionInterface = noInternetConnectionInterface;      this.subscription = retrofit.someService().someAPICall()          .subscribeOn(Schedulers.newThread())          .observeOn(AndroIDSchedulers.mainThread())          .subscribe(subscriber)          .retrywhen(retryFunction);  }  public voID cancel() {      if (this.subscription != null) {          this.subscription.unsubscribe();      }  }               private Func1<Observable<? extends Throwable>, Observable<?>> retryFunction = new Func1<Observable<? extends Throwable>, Observable<?>>() {      @OverrIDe      public Observable<?> call(Observable<? extends Throwable> observable) {          return observable.flatMap(new Func1<Throwable, Observable<?>>() {              @OverrIDe              public Observable<?> call(final Throwable throwable) {                  if (noInternetConnectionInterface!= null && (throwable instanceof IOException || throwable instanceof SocketTimeoutException)) {                      return noInternetConnectionInterface.noInternetConnection(throwable);                  }else{                      return Observable.error(throwable);                  }              }          });      }}

SomeAPICallAction只是一个简单的类,它包含了内部的改进API调用,唯一特别的是它的重试功能.重试函数将检查throwable是否是IOException或SocketTimeoutException,如果是,它将调用接口,以便我们可以向用户提供重试对话框,询问他们是否要重试该 *** 作.我们的用法类似于以下代码段

public class SomeActivity implement NoInternetConnectionInterface {    @OnClick(R.ID.@R_502_5554@)    public voID do(VIEw v) {        new SomeAPICallAction().execute(            new Subscriber(),            this        )    }    @OverrIDe    public PublishSubject<Integer> noInternetConnection(final Throwable throwable) {        Log.i("Dev", Thread.currentThread() + " Error!");        final PublishSubject<Integer> subject = PublishSubject.create();        runOnUiThread(new Runnable() {            @OverrIDe            public voID run() {                NoInternetDialogFragment dialog = NoInternetDialogFragment.newInstance();                dialog.setNoInternetDialogFragmentListener(new NoInternetDialogFragmentListener{                    @OverrIDe                    public voID onUserChoice(boolean retry, NoInternetDialogFragment dialog) {                        Log.i("Dev", Thread.currentThread() + " @R_502_5554@ Click!");                        if (retry) {                            subject.onNext(1);                        } else {                            subject.onError(throwable);                        }                        dialog.dismiss();                    }                });                dialog.show(getSupportFragmentManager(), NoInternetDialogFragment.TAG);            }        });        return subject;    }}

当我们使用Retrofit 1.9.0时,这个实现工作得非常完美.我们通过打开飞行模式进行测试,然后按下按钮执行API呼叫.

>第一次执行失败,我在重试功能中得到了UnkNownHostException.
>所以,我调用界面(Activity)来显示重试对话框
>我仍然在飞行模式下按重试按钮重复执行
>正如预期的那样,用户按下重试按钮后发生的每次执行都失败了,我总是在重试功能中得到UnkNownHostException.
>如果我一直按下重试按钮,重试对话框将永远显示,直到我关闭飞行模式.

但在我们更新我们的依赖关系之后

'com.squareup.retrofit2:retrofit:2.0.2''com.squareup.retrofit2:adapter-rxjava:2.0.2'

我们再试一次,但这次行为改变了,

>第一次执行失败,我在重试功能中获得了与之前相同的UnkNownHostException.
>所以,我调用界面(Activity)来显示重试对话框
>我仍然在飞行模式下按重试按钮重复执行
>但是这一次,在重试函数中,我得到了networkonmainthreadException而不是像它那样接收UnkNowHostException.
>因此条件不匹配,接口没有被调用,结果只有1个重试对话框呈现给用户.

以下是上面代码的日志

Thread[androID_0,5,main] Error!Thread[main,5,main] @R_502_5554@ Click!

你知道这会导致什么吗?任何建议,评论都会非常感激.

注意:以下是我们一直在使用并可能相关的其他依赖项.但是它们最近没有更新,从本项目开始就使用这些版本.

'com.jakewharton:butterknife:8.0.1''io.reactivex:rxandroID:1.1.0''io.reactivex:rxjava:1.1.0''com.Google.dagger:dagger-compiler:2.0''com.Google.dagger:dagger:2.0''javax.annotation:Jsr250-API:1.0'

更多信息

我只是将我的代码重置回到我们使用Retrofit 1.9的时候,我发现打印日志不同

Thread[Retrofit-IDle,5,main] Error!Thread[main,5,main] @R_502_5554@ Click!

不确定这是否与问题有关,但很明显,在1.9.0中,我将不同线程中的接口调用为2.0.0

最终编辑

在阅读了@JohnWowUs的答案并按照他提供的链接后,我发现在Retrofit 2中,网络调用默认是同步的

要解决我的问题,有两种方法可以解决此问题

1.)按照@JohnWowUs的建议,通过为retryFunction指定线程

this.subscription = retrofit.someService().someAPICall()  .subscribeOn(Schedulers.io())  .observeOn(AndroIDSchedulers.mainThread())  .subscribe(subscriber)  .retrywhen(retryFunction, Schedulers.io());

2.)创建改造对象时,在创建RxJavaCallAdapterFactory时指定线程

retrofit = new Retrofit.Builder()  .baseUrl(AppConfig.BASE_URL)  .clIEnt(clIEnt)  .addConverterFactory(GsonConverterFactory.create(getGson()))  .addCallAdapterFactory(     RxJavaCallAdapterFactory.createWithScheduler(       Schedulers.from(threadExecutor)     )   )  .build();

解决方法:

我认为问题在于,当您重新订阅时,由于在retrywhen中使用默认的trampoline调度程序而在主线程上订阅. Retrofit 1.9为您处理了调度,因此使用subscribeOn毫无意义.问题讨论是here.在Retrofit 2中我相信这已经改变了所以你应该尝试类似的东西

this.subscription = retrofit.someService().someAPICall()      .subscribeOn(Schedulers.io())      .observeOn(AndroIDSchedulers.mainThread())      .subscribe(subscriber)      .retrywhen(retryFunction, Schedulers.io());
总结

以上是内存溢出为你收集整理的android – 在我更新到Retrofit 2.0之后,在不同的线程中发布了对onNext的onNext调用全部内容,希望文章能够帮你解决android – 在我更新到Retrofit 2.0之后,在不同的线程中发布了对onNext的onNext调用所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1119457.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-29
下一篇 2022-05-29

发表评论

登录后才能评论

评论列表(0条)

保存