使用翻新和rxjava Android的多个并行API请求

时间:2019-12-13 06:54:10

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

我是Rx Java的新手,我有一种情况,我想从多个API获取数据。这些API彼此独立,但是我想在View中显示这些API的数据。因此,我想以某种方式进行这些API调用,以便可以同时获取每个API数据。我已经在使用翻新2。我对RX JAVA有所了解,但是我一次只知道如何发出一个请求。请帮助

改造剩余客户:

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;
}
}

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

ViewModel:

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);
        }

    }

}

2 个答案:

答案 0 :(得分: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 */ }
    )

答案 1 :(得分:1)

存储库类

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())
    }
}

ViewModel

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();
    }
}