【问题标题】:Multiple parallel api request using retrofit and rxjava Android使用改造和 rxjava Android 的多个并行 api 请求
【发布时间】:2019-12-16 16:05:16
【问题描述】:

我是 Rx java 的新手,我有一个场景,我想从多个 API 获取数据。这些 API 彼此独立,但我想在视图中显示来自这些 API 的数据。所以我想以这样的方式进行这些 API 调用,以便我可以同时获取每个 API 数据。我已经在使用改造 2。我对 RX JAVA 有点了解,但我只知道如何一次发出一个请求。请帮忙

Retorfit Rest 客户端:

public class RestClient {

    private static ApiService apiService = null;    
    public static ApiService getApiService(String url) {
        apiService = null;    
        HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
        interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);

        OkHttpClient okClient = new OkHttpClient.Builder().
                connectTimeout(1, TimeUnit.MINUTES).
                readTimeout(3, TimeUnit.MINUTES).
                addInterceptor(interceptor).build();    

        Gson gson = new GsonBuilder().setLenient().create();    

        Retrofit = new Retrofit.Builder()
                .baseUrl(url).client(okClient)
                .addConverterFactory(GsonConverterFactory.create(gson))
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .build();

        apiService = restAdapter.create(ApiService.class);    
        return apiService;
    }
}

API 服务接口:

public interface ApiService {


    @GET("v2/nearest_city")
    Observable<AqiDto> getAQI(@Query("lat") String latitude,
                          @Query("lon") String longitude,
                          @Query("key") String key);

    @GET("data/2.5/weather")
    Observable<WeatherDTO> getWeather(@Query("lat") String latitude,
                                  @Query("lon") String longitude,
                                  @Query("appid") String id);




}

存储库类:

public class SiteListRepository {

    private static final String TAG = "SITE_LIST_REPO";
    private final CompositeDisposable disposable;
    private Context mContext;
    private AppUtilities mAppUtilities;

    public SiteListRepository(Application application) {
        mContext = application.getApplicationContext();
        disposable = new CompositeDisposable();
        mAppUtilities = new AppUtilities(mContext);
    }

public Object getData() {


    disposable = Observable.merge(RestClient.getApiService(BASE_URL_AIR_INDEX).getAQI(EcoHubApplication.mAppSharedPreference.getLatitude(), EcoHubApplication.mAppSharedPreference.getLongitude(), "2664b262-6369-415c-aa5a-ef2bd9ccf1cf")
            .subscribeOn(Schedulers.newThread()), RestClient.getApiService(BASE_URL_OPEN_WEATHER).getWeather(EcoHubApplication.mAppSharedPreference.getLatitude(), EcoHubApplication.mAppSharedPreference.getLongitude(), "b6907d289e10d714a6e88b30761fae22")
            .subscribeOn(Schedulers.newThread())).observeOn(AndroidSchedulers.mainThread()).subscribe(obj -> {

        object = obj;

    });



    return object;
}
}

想要将这 2 个 API 调用合并在一起。

视图模型:

public class SiteListViewModel extends AndroidViewModel {

    private SiteListRepository siteListRepository;
    public MutableLiveData<AqiDto> aqiDTOMutableLiveData = new MutableLiveData<>();
    public MutableLiveData<WeatherDTO> weatherDTOMutableLiveData = new MutableLiveData<>();
    private Object object;

    public SiteListViewModel(@NonNull Application application) {
        super(application);
        siteListRepository = new SiteListRepository(application);
    }

    public void getData(){
        object = siteListRepository.getData();

        if (object instanceof AqiDto){
            aqiDTOMutableLiveData.setValue((AqiDto) object);
        } else if (object instanceof WeatherDTO){
            weatherDTOMutableLiveData.setValue((WeatherDTO) object);
        }

    }

}

【问题讨论】:

  • 您可以选择Single.zip(...)Single.zipArray(...)
  • Zip 并不是最有效的管理方式。我正在寻找合并。
  • 然后使用Single.merge(...)。另外,“不是最有效的方法”是什么意思?根据你的使用情况,zip就能达到你想要的效果。
  • proandroiddev.com/… 阅读,如果有错误请告诉我。
  • 文章的哪一部分说 zip 无效?因为在我看来,这篇文章是在赞扬它的能力。

标签: android rx-java rx-java2 rx-android


【解决方案1】:

您可以为此使用 Rxjava zip 函数

 @GET("v2/nearest_city")
    Observable<AqiDto> getAQI(@Query("lat") String latitude,
                          @Query("lon") String longitude,
                          @Query("key") String key);

    @GET("data/2.5/weather")
    Observable<WeatherDTO> getWeather(@Query("lat") String latitude,
                                  @Query("lon") String longitude,
                                  @Query("appid") String id);


    Observable.zip(ApiService.getAQI(your params),ApiService.getWeather(params)
    ,
    Function2<AqiDto, WeatherDTO,>> { 
        aqiDto, weatherDTO ->

        // Your operation here

        return weatherDTO;
    })
    .observeOn(AndroidSchedulers.mainThread())
    .doOnSubscribe { /* Loading Start */ }
    .doOnTerminate { /* Loading End */ }
    .subscribe(
            { /* Successfully Synced */ },
            { /* Having error */ }
    )

【讨论】:

【解决方案2】:

存储库类

public class SiteListRepository {

    private static final String TAG = "SITE_LIST_REPO";
    private final CompositeDisposable disposable;
    private Context mContext;
    private AppUtilities mAppUtilities;

    public SiteListRepository(Application application) {
        mContext = application.getApplicationContext();
        disposable = new CompositeDisposable();
        mAppUtilities = new AppUtilities(mContext);
    }

    public Observable getData() {
        return Observable.merge(RestClient.getApiService(BASE_URL_AIR_INDEX).getAQI(EcoHubApplication.mAppSharedPreference.getLatitude(), EcoHubApplication.mAppSharedPreference.getLongitude(), "2664b262-6369-415c-aa5a-ef2bd9ccf1cf")
            .subscribeOn(Schedulers.io()), RestClient.getApiService(BASE_URL_OPEN_WEATHER).getWeather(EcoHubApplication.mAppSharedPreference.getLatitude(), EcoHubApplication.mAppSharedPreference.getLongitude(), "b6907d289e10d714a6e88b30761fae22")
            .subscribeOn(Schedulers.io())).observeOn(AndroidSchedulers.mainThread())
    }
}

视图模型

public class SiteListViewModel extends AndroidViewModel {

    private SiteListRepository siteListRepository;
    public MutableLiveData<AqiDto> aqiDTOMutableLiveData = new MutableLiveData<>();
    public MutableLiveData<WeatherDTO> weatherDTOMutableLiveData = new MutableLiveData<>();
    private Object object;
    private CompositeDisposable disposables = new CompositeDisposable();

    public SiteListViewModel(@NonNull Application application) {
        super(application);
        siteListRepository = new SiteListRepository(application);
    }

    public void getData(){
        disposables.add( 
            siteListRepository.getData()
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe ( obj -> {
                     if (error != null) {
                         Log.e(TAG, error.message, error);
                     }
                     else {
                         if (obj instanceof AqiDto){
                             aqiDTOMutableLiveData.setValue((AqiDto) obj);
                         } else if (obj instanceof WeatherDTO){
                             weatherDTOMutableLiveData.setValue((WeatherDTO) obj);
                         }
                     }

                },
                error -> Log.e(TAG, error.message, error) // provide a second argument here to handle error
                )
        );


    }

@Override
protected void onCleared() {
    super.onCleared();
    disposable.clear();
    }
}

【讨论】:

  • @KanwarpreetSingh 我已经编辑了我的代码以解决异常问题。您还可以查看我发现的用于处理错误的有用链接github.com/ReactiveX/RxJava/wiki/Error-Handling-Operators
  • 您好,您可以添加有关如何处理异常的代码吗?如果任何 API 没有响应。
  • 我不明白你在哪里声明了错误。
猜你喜欢
  • 2020-01-29
  • 2021-09-04
  • 1970-01-01
  • 1970-01-01
  • 2022-01-24
  • 1970-01-01
  • 2018-12-09
  • 2021-06-04
  • 1970-01-01
相关资源
最近更新 更多