JSON
[
{
"countryName":"..."
},
{
"countryName":"..."
},
{
"countryName":"..."
} //etc... to 195 countries
]
Interface
public interface RetrofitInterface {
@GET("GetCountries.php")
Single<List<CountryModel>> getCountries();
}
Code
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) {
}
});
I'm trying to add 195 countries to the ChipGroup
but the app is freezing for a little bit during adding the chips, Firstly the code inside the doOnSuccess
method was in the onSuccess
method but the app was freezing for a little bit, So the code has been moved to doOnSuccess
method but I get this message Only the original thread that created a view hierarchy can touch its views.
I'm new with RxJava, Any solutions?
You've forgot to set scheduler on what it should be subscribed. By default, an Observable and the chain of operators that you apply to it will do its work, and will notify its observers, on the same thread on which its Subscribe method is called. so if you call it from the main thread it will be executed on the main thread. It's the reason why your app is freezing, because you make network request on the main thread, responsible for UI.
To fix it just set another scheduler with subscribeOn method:
.subscribeOn(Schedulers.io())
So in your case, it should looks something like this:
getCountries().doOnSuccess(countryModels - > {
...
}).observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io()) // Asynchronously subscribes to the observable on the IO scheduler.
.subscribe(
...
)
Detailed documentation: https://reactivex.io/documentation/operators/subscribeon.html
Also the article that can be helpful to understand thread handling in RxJava: https://proandroiddev.com/understanding-rxjava-subscribeon-and-observeon-744b0c6a41ea