Android   发布时间:2022-04-28  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了android – 在我更新到Retrofit 2.0之后,在不同的线程中发布了对onNext的onNext调用大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
在我们使用Retrofit 1.9时,我的同事创建了以下课程

@H_772_7@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@L_201_0@meservice()@L_201_0@meApiCall() .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); } } }); } }@H_772_8@

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

@H_772_7@public class SomeActivity implement NoInternetConnectionInterface { @OnClick(R.id.button) 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() + " Button Click!"); if (retry) { subject.onNext(1); } else { subject.onError(throwablE); } dialog.dismiss(); } }); dialog.show(getSupportFragmentManager(),NoInternetDialogFragment.TAG); } }); return subject; } }@H_772_8@

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

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

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

@H_772_7@'com.squareup.retrofit2:retrofit:2.0.2' 'com.squareup.retrofit2:adapter-rxjava:2.0.2'@H_772_8@

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

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

以下是上面代码的日志

@H_772_7@Thread[android_0,5,main] Error! Thread[main,main] Button Click!@H_772_8@

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

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

@H_772_7@'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'@H_772_8@

更多信息

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

@H_772_7@Thread[Retrofit-Idle,main] Button Click!@H_772_8@

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

最终编辑

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

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

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

@H_772_7@this.subscription = retrofit@L_201_0@meservice()@L_201_0@meApiCall() .subscribeOn(schedulers.io()) .observeOn(Androidschedulers.mainThread()) .subscribe(subscriber) .retryWhen(retryFunction,schedulers.io());@H_772_8@

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

@H_772_7@retrofit = new Retrofit.builder() .baseUrl(AppConfig.bASE_URL) .client(client) .addConverterFactory(GsonConverterFactory.create(getGson())) .addCallAdapterFactory( RxJavaCallAdapterFactory.createWithscheduler( schedulers.from(threadExecutor) ) ) .build();@H_772_8@

解决方法

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

@H_772_7@this.subscription = retrofit@L_201_0@meservice()@L_201_0@meApiCall() .subscribeOn(schedulers.io()) .observeOn(Androidschedulers.mainThread()) .subscribe(subscriber) .retryWhen(retryFunction,schedulers.io());@H_772_8@

大佬总结

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

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

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。