Retrofit里面的AsyncTask中的onPostExecute过早被触发

时间:2017-10-31 05:16:23

标签: android android-asynctask retrofit

我正在尝试将多个图像上传到服务器并通过Asynctask逐个发送。上传图像后,我将URL保存到本地列表并将其发送到onPostExecute进行处理。但是,我遇到了问题,因为onPostExecute过早地触发,doInBackground只返回一个空列表。

将URI传递给Asynctask

new UploadImages().execute(arrayUri);

我的Asynctask

private class UploadImages extends AsyncTask<Uri,Void,List<String>>{

        @Override
        protected List<String> doInBackground(Uri... params) {
            final ArrayList<String> urlList = new ArrayList<>();

            for(Uri uri : params) {
                File file = new File(uri.getPath());
                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(newIncidentLayout, R.string.sb_image_upload_error, Snackbar.LENGTH_SHORT);
                        snackbar.show();
                    }

                    @Override
                    protected void do4PositiveResponse(Response<FileInfo> response) {
                        FileInfo fileDetails = response.body();
                        urlList.add(fileDetails.getImage());
                        Log.d(TAG, "Uploaded Image");
                    }

                    @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(newIncidentLayout, R.string.sb_image_upload_error, Snackbar.LENGTH_SHORT);
                        snackbar.show();
                    }
                });
            }
            return urlList;
        }

        @Override
        protected void onPostExecute(List<String> urlList) {
            super.onPostExecute(urlList);

            //Post Incident
            setProgressMessage("Posting incident...");
            //other code here
        }
    }

我尝试添加一个thread.sleep,但结果永远不会相同。有时我得到一个列表作为回报,其他时候没有任何反应。

我不确定为什么会这样。我希望你能帮助我。感谢。

2 个答案:

答案 0 :(得分:4)

在android中,默认情况下会在后台线程中进行改装调用。您不应该/不需要使用AsyncTask

您可以在改进回调的方法onPostExecute(或您的案例onResponsedo4PositiveResponse)内编写do4NegativeResponse的代码。

答案 1 :(得分:1)

有两种类型的同步和异步调用。您正在使用异步的enqueue,因此您不需要使用异步任务。只需从代码中删除异步任务,并使用剩余的代码完成工作,而不是使用以下完整代码:

ArrayList<String> urlList = new ArrayList<>();

            for(Uri uri : params) {
                File file = new File(uri.getPath());
                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(newIncidentLayout, R.string.sb_image_upload_error, Snackbar.LENGTH_SHORT);
                        snackbar.show();
                    }

                    @Override
                    protected void do4PositiveResponse(Response<FileInfo> response) {
                        FileInfo fileDetails = response.body();
                        urlList.add(fileDetails.getImage());
                        Log.d(TAG, "Uploaded Image");
                    }

                    @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(newIncidentLayout, R.string.sb_image_upload_error, Snackbar.LENGTH_SHORT);
                        snackbar.show();
                    }
                });
            }

之后你在onPostExecute中做的事情是在完成for循环之后做的。