如何在没有runOnUiThread的情况下在AsyncTask中重构我的代码?

时间:2014-04-04 19:03:11

标签: android json api android-asynctask

你好Android开发者!我的旧代码和API 18的兼容性存在一个问题。 所有代码都在android 2.3中完美运行。但是,当我尝试在较新的API上运行它时,它会崩溃。我可以在没有runOnUiThread的情况下使用它来更新我的UI吗?我改变了什么?谢谢!

class GetDetails extends AsyncTask<String, String, String> {

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        pDialog = new ProgressDialog(QueryProduct.this);
        pDialog.setMessage("Loading product details. Please wait...");
        pDialog.setIndeterminate(false);
        pDialog.setCancelable(true);
        pDialog.show();
    }

    protected String doInBackground(String... params) {

        // updating UI from Background Thread
        runOnUiThread(new Runnable() {
            public void run() {

                int success;
                try {
                    List<NameValuePair> params = new ArrayList<NameValuePair>();
                    params.add(new BasicNameValuePair("id", id));

                    JSONObject json = jsonParser.makeHttpRequest(
                            url_product_detials, "GET", params);

                    success = json.getInt(TAG_SUCCESS);
                    if (success == 1) {
                        JSONArray productObj = json
                                .getJSONArray(TAG_PRODUCT);

                        JSONObject product = productObj.getJSONObject(0);

                        tvName = (TextView) findViewById(R.id.tvName);
                        tvName.setText(product.getString(TAG_NAME));

                    }else{

                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        });
        return null;
    }

    protected void onPostExecute(String file_url) {
        pDialog.dismiss();
    }
}

2 个答案:

答案 0 :(得分:4)

  

我可以在没有runOnUiThread的情况下使用它来更新我的UI吗?

YES!请做!移除runOnUiThread()并将结果返回onPostExecute()并在那里更新UI。这就是其他方法存在的原因。

你拥有它的方式,你正在UI运行所有背景资料,这违背了AsyncTask的目的。

您只需更改班级定义即可将int传递给onPostExecute()

class GetDetails extends AsyncTask<String, String, Integer>

然后return success中的doInBackground()。如果成功,请检查onPostExecute()中的值并更新UI

 protected void onPostExecute(Integer result)
 {
    if (result == 1)
    {
        // code to update UI

进一步说明

请务必仔细阅读AsyncTask Docs。创建此课程是为了让您可以在后台ThreaddoInBackground())上完成繁重的工作,例如网络内容,并更新其中的UI内置方法(另外3)。

  1. onPreExecute()可以在任务开始之前更新,例如a ProgressDialg
  2. onProgressUpdate()可以在doInBackground()处理时更新,例如通过调用publishProgress()
  3. 来处理下载文件的进度 当onPostExecute()完成时,会调用
  4. doInBackground() 在任务完成时更新您需要的任何内容,例如解雇a ProgressDialog

答案 1 :(得分:-2)

class GetDetails extends AsyncTask<String, String, String> {

@Override
protected void onPreExecute() {
    super.onPreExecute();
    pDialog = new ProgressDialog(QueryProduct.this);
    pDialog.setMessage("Loading product details. Please wait...");
    pDialog.setIndeterminate(false);
    pDialog.setCancelable(true);
    pDialog.show();
}

// Do your Background Task Inside it and inside it when you want to update the Ui 
// then call the method publishProgress. this call the method onProgressUpdate that 
// run on the UI thread and inside it you update your UI
protected String doInBackground(String... params) {



            int success;
            try {
                List<NameValuePair> params = new ArrayList<NameValuePair>();
                params.add(new BasicNameValuePair("id", id));

                JSONObject json = jsonParser.makeHttpRequest(
                        url_product_detials, "GET", params);

                success = json.getInt(TAG_SUCCESS);
                if (success == 1) {
                    JSONArray productObj = json
                            .getJSONArray(TAG_PRODUCT);

                    JSONObject product = productObj.getJSONObject(0);
                    String result = product.getString(tvName)
                   // Need To Update the Ui so call the method publishProgress(result );
                   // this will call  onProgressUpdate(String... values)  method and                                      
                   // String result i provide it to  so that i can update the text view                           
                   // in it.

                   //Update  in publish progress you can specify multiple String values
                   // and same received in onProgressUpdate as an array of values.
                   //publishProgress("value1","value2","value3")
                    publishProgress(result,"result2","result3");

                }else{

                }
            } catch (JSONException e) {
                e.printStackTrace();
            }

    return null;
}
// run on the Ui thread so inside it you can update your UI
protected void onProgressUpdate(String... values) 
        {
            super.onProgressUpdate(values);
      tvName = (TextView) findViewById(R.id.tvName);
      tvName.setText(values[0]);

      tvPrice = (TextView) findViewById(R.id.tvPrice);
      tvPrice.setText(values[1]); 
      tvAdress = (TextView) findViewById(R.id.tvAdress);
      tvAdress .setText(values[2]); 
      }
     protected void onPostExecute(String file_url) {

      pDialog.dismiss();
   }

}