当使用RxJava进行改装时,该应用程序会冻结一段时间



JSON

[
{
"countryName":"..."
},
{
"countryName":"..."
},
{
"countryName":"..."
} //etc... to 195 countries
]

接口

public interface RetrofitInterface {
@GET("GetCountries.php")
Single<List<CountryModel>> getCountries();
}

代码

new Retrofit.Builder().baseUrl(Constants.BASE_URL).addConverterFactory(GsonConverterFactory.create()).addCallAdapterFactory(RxJava3CallAdapterFactory.create()).build().create(RetrofitInterface.class).getCountries().doOnSuccess(countryModels - > {
for (CountryModel item: countryModels) {
Chip chip = new Chip(requireContext());
chip.setText(item.getCountryName());
fragmentCountriesBinding.fragmentCountriesChipGroupMain.addView(chip);
}
}).observeOn(AndroidSchedulers.mainThread()).subscribe(new SingleObserver < List < CountryModel >> () {
@Override
public void onSubscribe(@io.reactivex.rxjava3.annotations.NonNull Disposable d) {

}
@Override
public void onSuccess(@io.reactivex.rxjava3.annotations.NonNull List < CountryModel > countryModels) {

}
@Override
public void onError(@io.reactivex.rxjava3.annotations.NonNull Throwable e) {

}
});

我试图将195个国家添加到ChipGroup中,但在添加芯片的过程中,该应用程序冻结了一点。首先,doOnSuccess方法中的代码在onSuccess方法中,但该应用程序有一点冻结。因此,代码已移动到doOnSuccess方法,但我收到了此消息。只有创建视图层次结构的原始线程才能访问其视图。

我是RxJava的新手,有什么解决方案吗?

您忘记设置应该订阅的调度器。默认情况下,Observable和您应用于它的运算符链将在调用其Subscribe方法的同一线程上完成其工作,并通知其观察者。因此,如果您从主线程调用它,它将在主线程上执行。这就是你的应用程序冻结的原因,因为你在负责UI的主线程上发出网络请求。

要修复它,只需使用subscribeOn方法设置另一个调度器:

.subscribeOn(Schedulers.io())

所以在你的情况下,它应该看起来像这样:

getCountries().doOnSuccess(countryModels - > {
...
}).observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())   // Asynchronously subscribes  to the observable on the IO scheduler.
.subscribe(
...
)

详细文件:https://reactivex.io/documentation/operators/subscribeon.html

还有一篇有助于理解RxJava中的线程处理的文章:https://proandroiddev.com/understanding-rxjava-subscribeon-and-observeon-744b0c6a41ea

最新更新