如何使用 RXJava 和 Retrofit 重试连接服务器?
How can I retry to connect with the server using RXJava and Retrofit?
代码
new Retrofit.Builder().baseUrl(Constants.BASE_URL_FILES).addCallAdapterFactory(RxJava3CallAdapterFactory.create()).addConverterFactory(GsonConverterFactory.create()).build().create(RetrofitInterface.class).getCountries().observeOn(AndroidSchedulers.mainThread()).subscribe(new SingleObserver<List<CountryModel>>() {
@Override
public void onSubscribe(@io.reactivex.rxjava3.annotations.NonNull Disposable d) {
MainActivity.activityMainBinding.activityMainLinearProgressIndicatorLoading.setVisibility(View.VISIBLE);
}
@Override
public void onSuccess(@io.reactivex.rxjava3.annotations.NonNull List<CountryModel> countryModels) {
fragmentCountriesBinding.fragmentCountriesRecyclerViewCountries.setAdapter(new CountriesAdapter(requireContext(), countryModels));
MainActivity.activityMainBinding.activityMainLinearProgressIndicatorLoading.setVisibility(View.GONE);
}
@Override
public void onError(@io.reactivex.rxjava3.annotations.NonNull Throwable e) {
MainActivity.activityMainBinding.activityMainLinearProgressIndicatorLoading.setVisibility(View.GONE);
if (!MainActivity.isNetworkConnected(requireContext()))
Snackbar.make(MainActivity.activityMainBinding.getRoot(), R.string.no_internet, BaseTransientBottomBar.LENGTH_INDEFINITE).setMaxInlineActionWidth(1).setAction(R.string.retry, view ->
{
}).show();
else
Snackbar.make(MainActivity.activityMainBinding.getRoot(), R.string.something_went_wrong, BaseTransientBottomBar.LENGTH_INDEFINITE).setMaxInlineActionWidth(1).show();
}
});
RetrofitInterface
public interface RetrofitInterface {
@GET("GetCountries.php")
Single<List<CountryModel>> getCountries();
}
国家模型
public class CountryModel {
private int countryId;
private String countryName, countryIcon;
public int getCountryId() {
return countryId;
}
public String getCountryName() {
return countryName;
}
public String getCountryIcon() {
return countryIcon;
}
}
正如您在 onError
方法中看到的那样,我希望当用户单击重试按钮时必须再次重试与服务器的调用。
我花了 3 天时间阅读有关 retryWhen
方法的文章,并试图理解这张图片,但我无法理解它,而且我不知道如何在我的场景中使用它。
我的问题就是这样 我把赏金留给了可以帮助我的人,你可以在这里留下你的答案并在那里分享你的答案,直到我可以给你赏金。
我的解决方案很简单,只是 temporary/hack 而不是花几天时间使用 retryWhen()。
- 下面的代码我将您的请求调用封装到一个函数中。
-如果出现网络错误,只需对该函数进行递归调用,直到成功。
private void sendRequest(){
new Retrofit.Builder().baseUrl(Constants.BASE_URL_FILES).addCallAdapterFactory(RxJava3CallAdapterFactory.create()).addConverterFactory(GsonConverterFactory.create()).build().create(RetrofitInterface.class).getCountries().observeOn(AndroidSchedulers.mainThread()).subscribe(new SingleObserver<List<CountryModel>>() {
@Override
public void onSubscribe(@io.reactivex.rxjava3.annotations.NonNull Disposable d) {
MainActivity.activityMainBinding.activityMainLinearProgressIndicatorLoading.setVisibility(View.VISIBLE);
}
@Override
public void onSuccess(@io.reactivex.rxjava3.annotations.NonNull List<CountryModel> countryModels) {
fragmentCountriesBinding.fragmentCountriesRecyclerViewCountries.setAdapter(new CountriesAdapter(requireContext(), countryModels));
MainActivity.activityMainBinding.activityMainLinearProgressIndicatorLoading.setVisibility(View.GONE);
}
@Override
public void onError(@io.reactivex.rxjava3.annotations.NonNull Throwable e) {
MainActivity.activityMainBinding.activityMainLinearProgressIndicatorLoading.setVisibility(View.GONE);
if (!MainActivity.isNetworkConnected(requireContext()))
Snackbar.make(MainActivity.activityMainBinding.getRoot(), R.string.no_internet, BaseTransientBottomBar.LENGTH_INDEFINITE).setMaxInlineActionWidth(1).setAction(R.string.retry, view ->
{
}).show();
// IF NO NETWORK AVAILABLE just do recursive call of the method
sendRequest();
else
Snackbar.make(MainActivity.activityMainBinding.getRoot(), R.string.something_went_wrong, BaseTransientBottomBar.LENGTH_INDEFINITE).setMaxInlineActionWidth(1).show();
}
});
}
我找不到任何解决方案,所以我决定使用 retryUntil
而不是 retryWhen
,因为我没有找到任何答案。
代码
new Retrofit.Builder().baseUrl(Constants.BASE_URL_FILES).addCallAdapterFactory(RxJava3CallAdapterFactory.create()).addConverterFactory(GsonConverterFactory.create()).build().create(RetrofitInterface.class).getCountries().observeOn(AndroidSchedulers.mainThread()).subscribe(new SingleObserver<List<CountryModel>>() {
@Override
public void onSubscribe(@io.reactivex.rxjava3.annotations.NonNull Disposable d) {
MainActivity.activityMainBinding.activityMainLinearProgressIndicatorLoading.setVisibility(View.VISIBLE);
}
@Override
public void onSuccess(@io.reactivex.rxjava3.annotations.NonNull List<CountryModel> countryModels) {
fragmentCountriesBinding.fragmentCountriesRecyclerViewCountries.setAdapter(new CountriesAdapter(requireContext(), countryModels));
MainActivity.activityMainBinding.activityMainLinearProgressIndicatorLoading.setVisibility(View.GONE);
}
@Override
public void onError(@io.reactivex.rxjava3.annotations.NonNull Throwable e) {
MainActivity.activityMainBinding.activityMainLinearProgressIndicatorLoading.setVisibility(View.GONE);
if (!MainActivity.isNetworkConnected(requireContext()))
Snackbar.make(MainActivity.activityMainBinding.getRoot(), R.string.no_internet, BaseTransientBottomBar.LENGTH_INDEFINITE).setMaxInlineActionWidth(1).setAction(R.string.retry, view ->
{
}).show();
else
Snackbar.make(MainActivity.activityMainBinding.getRoot(), R.string.something_went_wrong, BaseTransientBottomBar.LENGTH_INDEFINITE).setMaxInlineActionWidth(1).show();
}
});
RetrofitInterface
public interface RetrofitInterface {
@GET("GetCountries.php")
Single<List<CountryModel>> getCountries();
}
国家模型
public class CountryModel {
private int countryId;
private String countryName, countryIcon;
public int getCountryId() {
return countryId;
}
public String getCountryName() {
return countryName;
}
public String getCountryIcon() {
return countryIcon;
}
}
正如您在 onError
方法中看到的那样,我希望当用户单击重试按钮时必须再次重试与服务器的调用。
我花了 3 天时间阅读有关 retryWhen
方法的文章,并试图理解这张图片,但我无法理解它,而且我不知道如何在我的场景中使用它。
我的问题就是这样
我的解决方案很简单,只是 temporary/hack 而不是花几天时间使用 retryWhen()。 - 下面的代码我将您的请求调用封装到一个函数中。 -如果出现网络错误,只需对该函数进行递归调用,直到成功。
private void sendRequest(){
new Retrofit.Builder().baseUrl(Constants.BASE_URL_FILES).addCallAdapterFactory(RxJava3CallAdapterFactory.create()).addConverterFactory(GsonConverterFactory.create()).build().create(RetrofitInterface.class).getCountries().observeOn(AndroidSchedulers.mainThread()).subscribe(new SingleObserver<List<CountryModel>>() {
@Override
public void onSubscribe(@io.reactivex.rxjava3.annotations.NonNull Disposable d) {
MainActivity.activityMainBinding.activityMainLinearProgressIndicatorLoading.setVisibility(View.VISIBLE);
}
@Override
public void onSuccess(@io.reactivex.rxjava3.annotations.NonNull List<CountryModel> countryModels) {
fragmentCountriesBinding.fragmentCountriesRecyclerViewCountries.setAdapter(new CountriesAdapter(requireContext(), countryModels));
MainActivity.activityMainBinding.activityMainLinearProgressIndicatorLoading.setVisibility(View.GONE);
}
@Override
public void onError(@io.reactivex.rxjava3.annotations.NonNull Throwable e) {
MainActivity.activityMainBinding.activityMainLinearProgressIndicatorLoading.setVisibility(View.GONE);
if (!MainActivity.isNetworkConnected(requireContext()))
Snackbar.make(MainActivity.activityMainBinding.getRoot(), R.string.no_internet, BaseTransientBottomBar.LENGTH_INDEFINITE).setMaxInlineActionWidth(1).setAction(R.string.retry, view ->
{
}).show();
// IF NO NETWORK AVAILABLE just do recursive call of the method
sendRequest();
else
Snackbar.make(MainActivity.activityMainBinding.getRoot(), R.string.something_went_wrong, BaseTransientBottomBar.LENGTH_INDEFINITE).setMaxInlineActionWidth(1).show();
}
}); }
我找不到任何解决方案,所以我决定使用 retryUntil
而不是 retryWhen
,因为我没有找到任何答案。