Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Studio error: "Method getText() must be called from the UI Thread, currently inferred thread is worker

i'm creating a CRUD operation in android studio but i kept getting errors. the error is when i check the LogCat this is what they show me

line 156-158
1907-1931/com.example.casquejo.loginadmin E/AndroidRuntime﹕ FATAL EXCEPTION: AsyncTask #2 Process: com.example.casquejo.loginadmin, PID: 1907 java.lang.RuntimeException: An error occured while executing doInBackground() Caused by: java.lang.NullPointerException atcom.example.casquejo.loginadmin.NewProductActivity$CreateNewProduct.doInBackground(NewProductActivity.java:85) at com.example.casquejo.loginadmin.NewProductActivity$CreateNewProduct.doInBackground(NewProductActivity.java:58) atcom.example.casquejo.loginadmin.NewProductActivity$CreateNewProduct.onPreExecute(NewProductActivity.java:67) atcom.example.casquejo.loginadmin.NewProductActivity$1.onClick(NewProductActivity.java:53)

can someone help me with this or can someone give an idea how to fix this` below is the code for my java class EditProductActivity.class

       package com.example.casquejo.loginadmin;

        import java.util.ArrayList;
        import java.util.List;
        import org.apache.http.NameValuePair;
        import org.apache.http.message.BasicNameValuePair;
        import org.json.JSONException;
        import org.json.JSONObject;
        import android.app.Activity;
        import android.app.ProgressDialog;
        import android.content.Intent;
        import android.os.AsyncTask;
        import android.os.Bundle;
        import android.util.Log;
        import android.view.View;
        import android.widget.Button;
        import android.widget.EditText;

        /**
        * Created by Casquejo on 9/14/2015.
        */
        public class NewProductActivity extends Activity {
    private ProgressDialog pDialog;

    JSONParser jsonParser = new JSONParser();
    EditText inputName;
    EditText inputPrice;
    EditText inputDesc;

    private static String url_create_product = "http://10.0.2.2/android_connect/create_product.php";

    private static final String TAG_SUCCESS = "success";

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.add_product);

        inputName = (EditText) findViewById(R.id.inputName);
        inputPrice = (EditText) findViewById(R.id.inputPrice);
        inputDesc = (EditText) findViewById(R.id.inputDesc);

        Button btnCreateProduct = (Button) findViewById(R.id.btnCreateProduct);
        btnCreateProduct.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View view) {
                String name = inputName.getText().toString();
                String price = inputPrice.getText().toString();
                String description = inputDesc.getText().toString();
                new CreateNewProduct().execute(name, price,description);
            }
        });
    }

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

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            pDialog = new ProgressDialog(NewProductActivity.this);
            pDialog.setMessage("Creating Product..");
            pDialog.setIndeterminate(false);
            pDialog.setCancelable(true);
            pDialog.show();

        }

        protected String doInBackground(String... args) {

            String name = args[0],
                    price = args[1],
                    description = args[2];

            List<NameValuePair> params = new ArrayList<NameValuePair>();
            params.add(new BasicNameValuePair("name", name));
            params.add(new BasicNameValuePair("price", price));
            params.add(new BasicNameValuePair("description", description));

            JSONObject json = jsonParser.makeHttpRequest(url_create_product,
                    "POST", params);

            Log.d("Create Response", json.toString());

            try {
                int success = json.getInt(TAG_SUCCESS);

                if (success == 1) {
                    Intent i = new Intent(getApplicationContext(), AllProductsActivity.class);
                    startActivity(i);
                    finish();
                }
                else {

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

            return null;
        }

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

    }
}
like image 471
DayllCasquejo Avatar asked Sep 14 '15 15:09

DayllCasquejo


3 Answers

the ide is referring to

  String name = txtName.getText().toString();
  String price = txtPrice.getText().toString();
  String description = txtDesc.getText().toString();

reading the values shouldn't be a problem, but in order to get rid of this warning/error, you can move it into the onClick and pass the values through execute(). E.g.

btnSave.setOnClickListener(new View.OnClickListener() {

    @Override
    public void onClick(View arg0) {
        String name = txtName.getText().toString();
        String price = txtPrice.getText().toString();
        String description = txtDesc.getText().toString();
        new SaveProductDetails().execute(name, price, description);
    }
});

when doInBackground is invoked, you can read those bac, through the former params, String... args. The three dots construct stays for varargs, and varargs can be access like an array, using the [] notation. In the case of the example,

args[0] contains the value of name, args[1] contains the value of price and args[2] contains the value of description.

like image 95
Blackbelt Avatar answered Nov 20 '22 01:11

Blackbelt


You're calling getText() from a background thread that's spawned by the AsyncTask.

First fetch the text and then call your async task. Here's an example

new SaveProductDetails()
    .execute(txtName.getText().toString(), 
        txtPrice.getText().toString(), 
        txtDesc.getText().toString());

And inside of SaveProductDetails doInBackground method:

String name = args[0],
       price = args[1],
       description = args[2];
like image 26
Simas Avatar answered Nov 20 '22 03:11

Simas


In an asynctask, the doInBackground(...) method runs in a background (non-UI) thread. As you can see in the error given, you are not allowed to interact with UI elements from a background thread.

You can either, pass the arguments into the background thread as suggested in one of the other answers, or, you could modify your asynctask such that the UI string values are read in the onPreExecute() method which IS executed on the UI thread (as is the onPostExecute() method).

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

private String name, price, description;

@Override
protected void onPreExecute() {
    super.onPreExecute();
    pDialog = new ProgressDialog(EditProductActivity.this);
    pDialog.setMessage("Saving product ...");
    pDialog.setIndeterminate(false);
    pDialog.setCancelable(true);
    pDialog.show();

    name = txtName.getText().toString();
    price = txtPrice.getText().toString();
    description = txtDesc.getText().toString();
}

protected String doInBackground(String... args) {
    //... Use as you would before

I'd suggest taking a look at a blogpost such as this one to understand more about AsyncTasks, how they work, how to use them including details such as which method runs on which thread.

like image 2
rcbevans Avatar answered Nov 20 '22 01:11

rcbevans