我正在尝试将多个图像上传到服务器并通过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,但结果永远不会相同。有时我得到一个列表作为回报,其他时候没有任何反应。
我不确定为什么会这样。我希望你能帮助我。感谢。
答案 0 :(得分:4)
在android中,默认情况下会在后台线程中进行改装调用。您不应该/不需要使用AsyncTask
。
您可以在改进回调的方法onPostExecute
(或您的案例onResponse
和do4PositiveResponse
)内编写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循环之后做的。