在AsyncTask完成时返回一个值

时间:2018-03-21 15:26:29

标签: java android asynchronous interface android-asynctask

我知道我可以在执行任务时使用接口作为委托做事,我也知道我可以使用.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任务完成)它将返回值更改为任务结果。因此,需要两次方法执行才能获得所需的值。

是否有任何解决办法让方法等待任务而不阻塞主线程?

2 个答案:

答案 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.