android - 并发api调用

时间:2017-03-09 22:04:54

标签: android api callback okhttp3

我正在寻找一种更好的方法:

APIManager.getInstance().processRequest(baseRequest, new Callback() {
  @Override
  public void onFailure(Call call, IOException e) {
      callback.failure(new Error(null, 400));
  }

  @Override
  public void onResponse(final Call call, Response response) throws IOException {
      String stringJson = response.body().string();
      try {
          JSONObject menuObject = new JSONObject(stringJson);

          final Menu menu = new Menu();
          if (!menuObject.isNull("category")) {

              final JSONArray categoriesArray = menuObject.getJSONArray("category");

              for (int i = 0; i < categoriesArray.length(); i++) {
                  final JSONObject category = categoriesArray.getJSONObject(i);
                  final MenuCategory menuCategory = new MenuCategory(category);
                  menu.getCategories().add(menuCategory);
                  getCategoryProductsRequest(storeId, menuCategory.getId(), priceType, new APICallback<ArrayList<MenuItem>>() {
                      @Override
                      public void success(final ArrayList<MenuItem> responseItems) {
                          for (final MenuItem menuItem : responseItems) {
                              getProductDetailsRequest(storeId, menuItem.getProductID(), priceType, new APICallback<ArrayList<MenuConfiguration>>() {
                                  @Override
                                  public void success(ArrayList<MenuConfiguration> response) {
                                      menuItem.setConfigurations(response);
                                      menuCategory.setItems(responseItems);
                                  }

                                  @Override
                                  public void failure(Error error) {
                                  }
                              });
                          }
                      }

                      @Override
                      public void failure(Error error) {
                      }
                  });
              }

              new Timer().schedule(new TimerTask() {
                  @Override
                  public void run() {
                      // this code will be executed after 2 seconds
                      callback.success(menu);
                  }
              }, 5000);
          }
      } catch (JSONException e) {
          callback.failure(new Error(null, 400));
          e.printStackTrace();
      }


  }

我想删除定时器延迟并在所有端点完成后发送回调。每个函数只是在我的API管理器中创建一个进程,我正在考虑使用队列系统,但我不确定我是否可以,因为我需要来自父端点的结果。

我已经在这里旋转了几天。

2 个答案:

答案 0 :(得分:0)

我可能会为您要求的总项目和目前收到的回复数量保留变量。一旦successResponses == totalItems,您就可以触发callback.success(菜单)。当然,由于您需要检索两个级别的多个对象,因此它有点复杂。

确保您同步对计数器变量的访问,因为您可能在不同的线程中收到了APICallback。

答案 1 :(得分:0)

使用我的APIManager内部的计数器解决了这个问题。

    private APIManager() {

        int cacheSize = 10 * 1024 * 1024;
        this.client = new OkHttpClient.Builder()
                .addInterceptor(new HttpLoggingInterceptor())
                .addInterceptor(new BaseInterceptor())
                .build();
    }

    public void processRequest(BaseRequest request, final Callback callback)
    {

        counter++;
        Callback tempCallback = new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                decrementCounter();
                callback.onFailure(call, e);
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                decrementCounter();
                callback.onResponse(call, response);
            }
        };

        client.newCall(request.getRequest()).enqueue(tempCallback);
    }

    private void decrementCounter() {
        counter--;
        if (counter <= 0) {
            counter = 0;

            if (listener != null) {
                listener.onAllCallsCompleted();
                listener = null;
            }
        }

    }