Привет разработчикам Android! У меня есть одна проблема с совместимостью моих старых кодов и API 18. Все приведенные ниже коды отлично работают в Android 2.3. Но когда я пытаюсь запустить его на новом API, он вылетает. Могу ли я использовать его без runOnUiThread для обновления моего пользовательского интерфейса? Что мне следует изменить? Спасибо!

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();
    }
}
0
user3499351 4 Апр 2014 в 23:03

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();
   }

}

-2
User10001 4 Апр 2014 в 20:30

Могу ли я использовать его без runOnUiThread для обновления моего пользовательского интерфейса?

ДА! Пожалуйста, сделай! Удалите 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 Thread doInBackground() UI
  1. onPreExecute() может обновляться перед запуском задачи, например, для ProgressDialg
  2. onProgressUpdate() может обновляться, пока doInBackground() все еще обрабатывается, например, при загрузке файла, путем вызова publishProgress()
  3. onPostExecute() вызывается, когда doInBackground() заканчивает обновлять все, что вам нужно, когда задача завершается, например, закрытие ProgressDialog
4
codeMagic 4 Апр 2014 в 19:28