如何使用rxjava为列表中的每个项目进行改造api请求?

时间:2018-01-11 05:23:03

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

我对RxJava很新,虽然我看到了与我要问的问题有关的多个问题,但我似乎无法将它们完全分开。

我有一个包含以下数据的PostPatrol对象:

public class PostPatrol {
   String checkpoint_name;
   String status;
   int user;
   String detail;
   List<String> photos;

   public PostPatrol(int cpId, String checkpoint_name, String detail, List<String> photos, String detail) {
       this.cpId = cpId;
       this.checkpoint_name = checkpoint_name;
       this.detail = detail;
       this.photos = photos;
       this.status = status;
   }

   //getters and setters
}

我现在要做的是将本地照片列表保存到此PostPatrol记录中,但在此之前我必须逐个上传照片并进行改造,取回网址并将其保存到列表中然后我设置为PostPatrol记录的照片。

一旦我保存了某个PostPatrol记录所需的所有详细信息,我就会通过改造再次发送。

目前,我这样做:

  1. 我将照片传递给一个逐个上传图片的功能
  2. 功能如下:

    private void uploadImage(List<String> photos, String folder, long requestId) {
        final int size = photos.size();
        final long reqId = requestId;
    
        for (String path : photos) {
            File file = new File(path);
            RequestBody requestBody = RequestBody.create(MediaType.parse("image/*"), file);
            MultipartBody.Part body = MultipartBody.Part.createFormData("image", file.getName(), requestBody);
            RequestBody folderName = RequestBody.create(MediaType.parse("text/plain"), folder);
    
            ApiEndpointInterface apiEndpointInterface = RetrofitManager.getApiInterface();
    
            Call<FileInfo> call4File = apiEndpointInterface.postFile(body, folderName);
    
            call4File.enqueue(new ApiCallback<FileInfo>() {
                @Override
                protected void do4Failure(Throwable t) {
                    Log.d(TAG, t.toString());
                    snackbar = Snackbar.make(viewPendingRequestLayout, R.string.sb_image_upload_error, Snackbar.LENGTH_SHORT);
                    snackbar.show();
                    position++;
                }
    
                @Override
                protected void do4PositiveResponse(Response<FileInfo> response) {
                    Log.d(TAG, "Uploaded Image");
                    FileInfo fileDetails = response.body();
                    listUrls.add(fileDetails.getImage());
                    position++;
                    if (position == size) {
                        postRequest(reqId);
                        position = 0;
                    }
                }
    
                @Override
                protected void do4NegativeResponse(Response<FileInfo> response) {
                    String bodyMsg = "";
                    try {
                        bodyMsg = new String(response.errorBody().bytes());
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    Log.d(TAG, bodyMsg);
                    snackbar = Snackbar.make(viewPendingRequestLayout, R.string.sb_image_upload_error, Snackbar.LENGTH_SHORT);
                    snackbar.show();
                    position++;
                }
            });
        }
    }
    
  3. do4PositiveResponse中,我使用局部变量来跟踪我是否已将所有照片上传到将列表保存到PostPatrol记录的功能之前。但有时候,我会发现照片根本没有上传的问题,因为它太晚或太早都没有上传。

    1. 这是我在postRequest()

      上的代码
      private void postRequest(long requestId) {
          if(mapIdPatrol.containsKey(requestId)){
              PostPatrol postPatrol = mapIdPatrol.get(requestId);
              postPatrol.setPhotos(listUrls);
              postPatrolRequest(postPatrol, requestId);
          }
          listUrls = new ArrayList<>();
      }
      
    2. 最后我的代码在postPatrolRequest()

      private void postPatrolRequest(final PostPatrol postPatrol, final long requestId){
          ApiEndpointInterface apiEndpointInterface = RetrofitManager.getApiInterface();
          Call<ResponseId> call4Handle = apiEndpointInterface.handleCheckpoint(postPatrol);
      
          call4Handle.enqueue(new ApiCallback<ResponseId>() {
              @Override
              protected void do4Failure(Throwable t) {
                  finishUploading();
                  Log.d(TAG, t.toString());
              }
              @Override
              protected void do4PositiveResponse(Response<ResponseId> response) {
                  RequestsDataSource.removeRequest(getApplication(),requestId);
                  finishUploading();
              }
              @Override
              protected void do4NegativeResponse(Response<ResponseId> response) {
                  finishUploading();
                  String bodyMsg = "";
                  try {
                      bodyMsg = new String(response.errorBody().bytes());
                  } catch (IOException e) {
                      e.printStackTrace();
                  }
                  Log.d(TAG, bodyMsg);
                  snackbar = Snackbar.make(viewPendingRequestLayout, getResources().getText(R.string.sb_negative_response), Snackbar.LENGTH_SHORT);
                  snackbar.show();
              }
          });
      
      }
      
    3. 我知道这是非常低效的,所以我希望你的帮助,所以我可以尝试使用RxJava找到解决方法。谢谢。

1 个答案:

答案 0 :(得分:1)

操作是原子的吗?即如果通过Retrofit保存一些照片失败,你还需要继续吗?

无论如何,大致解决方案将是类似的(伪代码):

Observable<String> urls = Observable.from(listOfPhotoFilePaths)
    .flatMapDelayError(path -> { return retrofit.save(readFile(path))})
    .toList()

Observable<PostPatrol> pp = urls
    .map(list -> { return new PostPatrol(list)})