Issue
I know that I can use interfaces as delegates to do things while performing task, I also know that I can use get()
to make an AsyncTask synchronous, But I don't want to block the UI thread.
I used AsyncTask
with OkHttp
to upload a file and get a result like this:
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);
}
}
}
then I create the task in method like this:
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];
}
But the problem is that the task gets thrown in the background and the method continues working, so in the first execution of the method it returns the default value of boolResult[0] which is false, but in the second execution (After the task finishes) it changes the return value to whatever is result of the task. So it takes two method executions to get the desired value.
Is there any work-around to make a method wait for the task without blocking the main thread?
Solution
If you don't want to block the UI thread, then you have to let the work done in parallel. In that case it is not possible to return the result from the UI thread.
There for your primary question
Is there any work-around to make a method wait for the task without blocking the main thread?
itself doesn't make any sense.
The solution
- Make filter a void method.
- wrap everything you want to do with the
result in another method (
onResult(boolean result)
) and call it fromonCompleteTask()
. - Do whatever you want to do in there.
Answered By - Bertram Gilfoyle
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.