Android Studio错误:“必须从UI线程调用方法getText(),当前推断的线程是worker

时间:2015-09-14 15:17:08

标签: java android multithreading android-asynctask

我正在android studio中创建一个CRUD操作,但我不断收到错误。错误是当我检查LogCat这是他们给我看的时候

  

第156-158行   1907-1931 / com.example.casquejo.loginadmin E / AndroidRuntime:致命   EXCEPTION:AsyncTask#2   处理:com.example.casquejo.loginadmin,PID:1907   java.lang.RuntimeException:执行时发生错误   doInBackground()     引起: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)

有人可以帮我解决这个问题,或者有人能想出如何解决这个问题`下面是我的java类的代码 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();
        }

    }
}

5 个答案:

答案 0 :(得分:6)

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.

答案 1 :(得分:5)

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];

答案 2 :(得分:2)

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.

答案 3 :(得分:0)

You can read this Using Variables on UI Thread from Worker Thread .
In your question, you are trying to access text of TextView from background thread. In-order to be consistent as You should not do this because their might be possibility that main thread(UI thread setting TextView at the same time). To avoid such sceneries you can to something like this:

class SaveProductDetails extends AsyncTask<String, String, String>{
      //create constructor and pass values of text view in it
      String textViewValue1;
      public SaveProductDetails (String textViewValue1 ){
           this.textViewValue1=textViewValue1
      }

     //other code below
} 

答案 4 :(得分:0)

您不需要将值传递给execute方法。 将名称,价格和描述变量设置为全局变量。 要从按钮上获取EditTest的值,请单击下面的代码:

每次您需要单击按钮以获取JSON数据。

btnSave.setOnClickListener(new View.OnClickListener() {

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

现在,无论您输入什么名称,价格和描述都有其价值。

现在你的CreateNewProduct类看起来像这样:

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) {

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

}