我对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记录的所有必需的详细信息,我便再次通过改进将其发送出去。

目前,我正在以这种方式进行操作:


我将照片传递给函数以一张一张地上传图像
函数是这样的:

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



do4PositiveResponse中,我使用局部变量来跟踪是否已上传所有照片,然后再将它们发送到将列表保存到PostPatrol记录的函数中。不过有时候,我会遇到问题,因为它们开火太晚或太早,根本没有上传照片。


这是我在postRequest()上的代码

private void postRequest(long requestId) {
    if(mapIdPatrol.containsKey(requestId)){
        PostPatrol postPatrol = mapIdPatrol.get(requestId);
        postPatrol.setPhotos(listUrls);
        postPatrolRequest(postPatrol, requestId);
    }
    listUrls = new ArrayList<>();
}

最后是我在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();
        }
    });

}



我知道这是非常低效的,所以我希望得到您的帮助,因此我可以尝试使用RxJava来找到解决方法。谢谢。

最佳答案

操作是原子的吗?即,如果通过翻新保存某些照片失败,您是否还需要继续?

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

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

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

10-07 12:17