如何停止执行UI线程,直到异步任务完成,以返回在android中的AsyncTask中获取的值

2 android return-value execution ui-thread android-asynctask

我有一个类,我已经编写了一个AsyncTask来从网上获取Json.

public class MyAsyncGetJsonFromUrl extends AsyncTask<Void, Void, JSONObject> {
    Context context_;
    String url_;
    List<NameValuePair> params_;

    public MyAsyncGetJsonFromUrl(Context context_, List<NameValuePair> params_, String url_) {
        this.context_ = context;
        this.params_ = params_;
        this.url_ = url_;
    }

    @Override
    protected JSONObject doInBackground(Void... params) {
        JSONObject jObj_ = null;
        try {
            DefaultHttpClient httpClient = new DefaultHttpClient();
            HttpPost httpPost = new HttpPost(url_);
            httpPost.setEntity(new UrlEncodedFormEntity(params_));

            HttpResponse httpResponse = httpClient.execute(httpPost);
            HttpEntity httpEntity = httpResponse.getEntity();
            InputStream is_ = httpEntity.getContent();

            BufferedReader reader = new BufferedReader(new InputStreamReader(is, "iso-8859-1"), 8);
            StringBuilder sb = new StringBuilder();
            String line = null;
            while ((line = reader.readLine()) != null) {
                sb.append(line + "\n");
            }
            is_.close();
            String json_ = sb.toString();
            Log.e("JSON", json);

            jObj_ = new JSONObject(json_);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return jObj_;
    }

    protected void onPostExecute(JSONObject jObj_) {
        jObj = jObj_;
    }
}
Run Code Online (Sandbox Code Playgroud)

此类中还有一个方法,它将此Json对象返回给调用该方法的Activity.

public JSONObject getJSONFromUrl(String url, List<NameValuePair> params) {
    new MyAsyncGetJsonFromUrl(context, params, url).execute();
    return jObj;
}
Run Code Online (Sandbox Code Playgroud)

现在问题是在启动AsyncTask后new MyAsyncGetJsonFromUrl(context, params, url).execute();立即return jObj;调用该行并返回null.所以我想停止执行,直到异步任务完成.请不要将此问题视为重复,因为没有其他问题与此方案完全相同

Anu*_*kur 6

异步任务是异步的.这意味着它们在后台独立于程序当前线程执行(它们在后台线程中运行).因此,在异步任务完成之前,您不应该尝试停止执行程序.

所以你有两个选择:

  • 在UI线程本身而不是在异步任务中运行代码

  • 从异步任务onPostExecute()方法中分配值

如果您决定使用异步任务并使用选项B,则可以使用一些静态变量或类似的东西,可以在异步任务结束时将JSON对象的值分配给该变量,以后可以访问.您还可以对onPostExecute()方法本身中的JSON对象执行任何后处理(例如:解析对象并将其显示给用户),因为在异步任务完成其操作之后,此方法在UI线程上运行后台线程.

如果您需要异步任务的返回值,您可以执行以下操作:

jObj = new MyAsyncGetJsonFromUrl(context, params, url).execute().get(); 
Run Code Online (Sandbox Code Playgroud)

在这种情况下,程序将等待计算完成,除非存在异常,例如线程被中断或取消(由于内存限制等).但通常不建议采用这种方法.异步任务的要点是允许异步操作,因此不应该停止程序执行.

返回值将doInBackground()作为参数传递给OnPostExecute()方法.您不必在onPostExecute中放置返回值,因为它在UI线程本身上执行.只需使用结果,并使用它做你需要的.