我知道我可以在执行任务时使用接口作为委托做事,我也知道我可以使用.get()来使AsyncTask同步,但我不想阻止UI线程。
我使用AsyncTask和OkHttp上传文件并获得如下结果:
static class UploadFile extends AsyncTask<Void, Void, String> {
private TaskInterface<String, Float> delegate = null;
private String url;
private File file;
private MediaType fileType;
private String ret = "NULL";
UploadFile(String url, File file, MediaType fileType, TaskInterface<String, Float> delegate){
this.delegate = delegate;
this.url = url;
this.file = file;
this.fileType = fileType;
}
@Override
protected void onPreExecute() {
if (delegate != null){
delegate.onPreCompleteTask();
Log.d("UPLOADING:", "File : " + file.getName());
}
}
@Override
protected String doInBackground(Void...voids) {
RequestBody body = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("upload", file.getName(),RequestBody.create(fileType, file))
.build();
Request request = new Request.Builder()
.url(url)
.post(body)
.build();
try {
Response response = okhttpclient.newCall(request).execute();
ret = response.body().string();
} catch (Exception e){
e.printStackTrace();
Log.e("HttpClient", "Upload: " + e.getMessage());
}
return ret;
}
@Override
protected void onPostExecute(String result) {
if (delegate != null){
delegate.onCompleteTask(result);
Log.d("ON UPLOAD POST EXECUTE", result);
}
}
}
然后我用这样的方法创建任务:
Boolean validateVCode(File file){
final boolean[] boolResult = new boolean[1];
new UploadFile("http://localhost/doThings.php",
file,
myMediaType,
new TaskInterface<String, Float>() {
@Override
public void onPreCompleteTask(){
processDialog.show();
}
@Override
public void onCompleteTask(String result) {
processDialog.dismiss();
boolResult[0] = result.contains("true");
}
}).execute();
return boolResult[0];
}
但问题是任务在后台被抛出并且方法继续工作,所以在方法的第一次执行时它返回默认值boolResult [0],这是假的,但是在第二次执行时(After任务完成)它将返回值更改为任务结果。因此,需要两次方法执行才能获得所需的值。
是否有任何解决办法让方法等待任务而不阻塞主线程?
答案 0 :(得分:0)
如果您不想阻止UI线程,那么您必须并行完成工作。在这种情况下,无法从UI线程返回结果。
longer discussion about the motivation
这是您的主要问题
是否有任何解决办法让方法等待没有的任务 阻止主线程?
本身没有任何意义。
onResult(boolean result)
)并从onCompleteTask()
调用它。答案 1 :(得分:0)
我认为我找到了两个解决问题的方法:
调用“onCompleteTask(String result)”中的检查方法:
@Override
public void onCompleteTask(String result){
processDialog.dismiss();
checkingMethod(result.contains("true"));
}
实施RxJava:,解释为here.