【发布时间】:2018-08-30 19:25:57
【问题描述】:
我知道我可以在执行任务的同时使用接口作为委托来做事,我也知道我可以使用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] 的默认值是 false,但在第二次执行中(之后任务完成)它将返回值更改为任务的结果。因此需要执行两次方法才能获得所需的值。
有什么变通方法可以让方法在不阻塞主线程的情况下等待任务?
【问题讨论】:
-
你不能阻止一个方法而不阻塞它正在运行的线程。所有的库,包括 SDK 本身,都因此使用监听器模式。
-
感谢您的澄清。那么,我可以创建一个不同的线程并在不影响性能的情况下阻止它吗?
-
主线程没有性能损失? - 是的
-
虽然我不建议在android上创建自己的线程
-
你不需要 AsyncTask 来使用 OkHTTP... 它已经有回调函数
标签: java android asynchronous interface android-asynctask