How to update TextView from AsyncTask?

2

I have seen in this example, updating the TextView field from within AsyncTask but I can not repeat that in my code, and what do you think this is not even possible or is it?

protected String doInBackground(String... params) {

    // updating UI from Background Thread
    runOnUiThread(new Runnable() {
        public void run() {
            // Check for success tag
            int success;
            try {
                // Building Parameters
                List<NameValuePair> params = new ArrayList<NameValuePair>();
                params.add(new BasicNameValuePair("pid", pid));

                // getting product details by making HTTP request
                // Note that product details url will use GET request
                JSONObject json = jsonParser.makeHttpRequest(
                        url_product_detials, "GET", params);

                // check your log for json response
                Log.d("Single Product Details", json.toString());

                // json success tag
                success = json.getInt(TAG_SUCCESS);
                if (success == 1) {
                    // successfully received product details
                    JSONArray productObj = json
                            .getJSONArray(TAG_PRODUCT); // JSON Array

                    // get first product object from JSON Array
                    JSONObject product = productObj.getJSONObject(0);

                    // product with this pid found
                    // Edit Text
                    txtName = (EditText) findViewById(R.id.inputName);
                    txtPrice = (EditText) findViewById(R.id.inputPrice);
                    txtDesc = (EditText) findViewById(R.id.inputDesc);

                    // display product data in EditText
                    txtName.setText(product.getString(TAG_NAME));
                    txtPrice.setText(product.getString(TAG_PRICE));
                    txtDesc.setText(product.getString(TAG_DESCRIPTION));

                }else{
                    // product with pid not found
                }
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
    });

    return null;
}

My Code!

protected String doInBackground(String... params) {

    runOnUiThread(new Runnable() {      
        public void run() {
                List<NameValuePair> param = new ArrayList<NameValuePair>();
                param.add(new BasicNameValuePair("id", pid));   

                //Conexao
                JSONObject json = jsonParser.makeHttpRequest(Extras.urlListarProdutosID(), "POST", param);

                  try {
                        int success = json.getInt("sucesso");
                        if (success == 1) {
                            JSONArray productObj = json.getJSONArray("produto");
                            JSONObject produto = productObj.getJSONObject(0);

                            nome = (EditText) findViewById(R.id.nome);                      

                            nome.setText(produto.getString("nome"));                     

                        }                                       

                    } catch (JSONException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
    });
    return null;
}
    
asked by anonymous 26.03.2014 / 17:24

3 answers

4

The official documentation for Android is here

  

Asynchronous Task is defined as a computation that runs on a Background Thread and the result is published on the Interface Thread (UI Thread). On Android we have 3 generic types, called Params, Progress and Result, and 4 steps called onPreExecute, ofInBackground, onProgressUpdate and onPostExecute.

Generic AsyncTask types

  • Params - Type of parameter sent to the task
  • Progress - Type of the progress unit parameter to be used in the task
  • Result - Task result type

Not all parameters are used in Task, to ignore a parameter use the class Void

private class MyTask extends AsyncTask<Void, Void, Void> { ... }

Four steps

When the task is executed it goes through 4 steps:

    OnPreExecute () - Invoked in the Thread UI before execution.

  • of InBackground (Params ...) - Invoked after onPreExecute () and runs on a separate Thread.

  • onProgressUpdate (Progress ...), invoked on the UI Thread after the publishProgress (Progress ...) method is called inside the doInBackground (...)

  • onPostExecute (Result), invoked after the end of the InBackground (...)

For an XML like this:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_width="fill_parent"
              android:layout_height="fill_parent"
        >
    <EditText
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/editText"/>
    <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Task"
            android:id="@+id/button"/>
</LinearLayout>

You could do AsyncTask to update like this:

public class MyActivity extends Activity {

    private EditText editText;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        this.editText = (EditText) findViewById(R.id.editText);
        findViewById(R.id.button).setOnClickListener(getOnClickButton());
        Log.d("test","onCreate");
    }

    private View.OnClickListener getOnClickButton() {
        return new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Log.d("test","onClick");
                startTask();
            }
        };
    }

    private void startTask() {
        new Task().execute();
    }
    private class Task extends AsyncTask<Void, Void, Void> {
        private String text;

        @Override
        protected Void doInBackground(Void... voids) {
            Log.d("test","doInBackground");
            this.text = "Xubaduba";
            return null;
        }

        protected void onPostExecute(Void result) {
            Log.d("test","onPostExecute");
            editText.setText(this.text);
        }
    }
}

In Log you would get something like:

    
26.03.2014 / 17:44
3

When a AsyncTask is executed it goes through 4 works:

onPreExecute() - Is executed in the UI thread and before the task is executed.

doInBackground(Params...) - Is executed in background thread soon after onPreExecute()

onProgressUpdate(Progress...) - Is executed in the UI thread when it is invoked by publishProgress(Progress...) , this is where you must update the View during the course of AsyncTask .

onPostExecute(Result) - Is executed in the UI thread shortly after AsyncTask is finished. Here you can also update to View

For a full explanation see AsyncTask

    
26.03.2014 / 17:37
1

What happens is that you are trying to update your View inside the method of InBackground () that runs on another thread and this is not allowed.

You can update your View in the following AsyncTask methods: publishProgress (), onPreExecute (), and onPostExecute (). To do this, within any of these methods you add the following snippet:

EditText nome = (EditText) findViewById(R.id.nome);                      
nome.setText(produto.getString("nome"));  

Getting something like:

@Override
protected void onPostExecute(Boolean result) {
    super.onPostExecute(result);
    EditText nome = (EditText) findViewById(R.id.nome);                      
    nome.setText(produto.getString("nome"));  
}

Simple!

    
26.03.2014 / 17:54