【问题标题】:How to make multiple network calls at once using RxJava2 + Retrofit2如何使用 RxJava2 + Retrofit2 一次进行多个网络调用
【发布时间】:2020-03-03 06:22:21
【问题描述】:

我正在使用多个 api 调用从服务器获取数据,因为我正在使用 Retrofit@ 和 RxJava2。在我的 api 服务类中,我有 2 个 get 请求,它们都单独运行,因为数据没有完全到来。我想要同时从两个 api 获取所有数据。目前我正在获取类似这样的数据,我想要一些更好的方法来处理多个 api 调用。

下面是我的代码:

ApiService.class

public interface ApiService {

@GET("Categoery_api")
Observable<List<MenuModel>> getData();

@GET("Recent_six_post_api")
Observable<List<FlashStoryModel>> getFlashStory();

}

MainActivity.java

 private void getMenu(){

    Retrofit retrofit = RetrofitClient.getInstance();
    ApiService myApi = retrofit.create(ApiService.class);

    myApi.getData().subscribeOn(Schedulers.io())
                   .observeOn(AndroidSchedulers.mainThread())
                   .subscribe(new Observer<List<MenuModel>>() {
                       @Override
                       public void onSubscribe(Disposable d) {

                       }

                       @Override
                       public void onNext(List<MenuModel> menuModels) {

                           if(menuModels.size() > 0){

                               menuProg.setVisibility(View.INVISIBLE);
                               list.addAll(menuModels);

                               adapter = new MenuAdapter(list,getApplicationContext());
                               menuRecycler.setAdapter(adapter);
                           }
                       }

                       @Override
                       public void onError(Throwable e) {

                           menuProg.setVisibility(View.INVISIBLE);
                           Toast.makeText(getApplicationContext(),e.getMessage(),Toast.LENGTH_SHORT).show();
                       }

                       @Override
                       public void onComplete() {

                       }
                   });
}

private void getFlashStory(){

    Retrofit retrofit = RetrofitClient.getInstance();
    ApiService apiService = retrofit.create(ApiService.class);
    apiService.getFlashStory().subscribeOn(Schedulers.io())
                              .observeOn(AndroidSchedulers.mainThread())
                              .subscribe(new Observer<List<FlashStoryModel>>() {
                                  @Override
                                  public void onSubscribe(Disposable d) {

                                  }

                                  @Override
                                  public void onNext(List<FlashStoryModel> flashStoryModels) {

                                      if(flashStoryModels.size() > 0){

                                          prog1.setVisibility(View.INVISIBLE);

                                          storyList.addAll(flashStoryModels);
                                          flashStoryAdapter = new FlashStoryAdapter(getActivity(),storyList);
                                          flashStory.setAdapter(flashStoryAdapter);

                                          final Handler handler = new Handler();
                                          final Runnable update = new Runnable() {
                                              @Override
                                              public void run() {
                                                  if (currentPage == 6) {
                                                      currentPage = 0;
                                                  }
                                                  flashStory.setCurrentItem(currentPage++, true);
                                              }
                                          };

                                          timer = new Timer(); // This will create a new Thread
                                          timer.schedule(new TimerTask() { // task to be scheduled
                                              @Override
                                              public void run() {
                                                  handler.post(update);
                                              }
                                          }, DELAY_MS, PERIOD_MS);

                                      }
                                  }

                                  @Override
                                  public void onError(Throwable e) {

                                      prog1.setVisibility(View.INVISIBLE);
                                      Toast.makeText(getActivity(),e.getMessage(),Toast.LENGTH_SHORT).show();
                                  }

                                  @Override
                                  public void onComplete() {

                                  }
                              });
}

有人请告诉我如何才能达到预期的结果。任何帮助将不胜感激。

谢谢

【问题讨论】:

  • 你应该使用 Rxjava zip 操作符

标签: android retrofit2 rx-java2


【解决方案1】:

使用Observable.zip(...)

Observable.zip(
    apiService.getFlashStory(),
    apiService.getData(),
    BiFunction< List<FlashStoryModel>, List<MenuModel>, Unit> { r1, r2, _ ->
        // r1 is result from apiService.getFlashStory()
        // r2 is result from apiService.getData()

        // Do something here.

        // For example, this is what your code do above for apiService.getData()
        if(r2.size() > 0){
            menuProg.setVisibility(View.INVISIBLE);
            list.addAll(r2);

            adapter = new MenuAdapter(list,getApplicationContext());
            menuRecycler.setAdapter(adapter);
        }

    }

).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())

这是真正的 BiFunction。

object: BiFunction<P, Q, R> {
    override fun apply(t1: P, t2: Q): R {
        TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
    }
}

但我是这样写的。

BiFunction<P, Q, R> { r1, r2, returnValue -> 
    TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}

【讨论】:

  • 如何从两个 api 调用中获取响应,请您详细解释一下,因为我无法理解如何获取响应并将它们显示在列表中。
  • 订阅此Observable.zip(...)后,当两个api都得到响应时,它将触发BiFunction中的apply()函数。
  • 所以在 BiFunction 中我需要捕获所有响应
  • 是的,您可以在这里看到您的回复。
【解决方案2】:

您可以同时调用,但要启动新线程,不要为此使用主线程。 myApi.getData().subscribeOn(Schedulers.newThread()) .observeOn(Schedulers.newThread())

这样您可以避免应用程序挂起或滞后。

【讨论】:

    猜你喜欢
    • 2017-05-27
    • 1970-01-01
    • 2020-07-15
    • 2018-02-13
    • 1970-01-01
    • 2017-08-09
    • 1970-01-01
    • 2018-03-09
    • 1970-01-01
    相关资源
    最近更新 更多