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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/32568340/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 20:24:13  来源:igfitidea点击:

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

javaandroidmultithreadingandroid-asynctask

提问by DayllCasquejo

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

我正在 android studio 中创建一个 CRUD 操作,但我一直收到错误。错误是当我检查 LogCat 这就是他们向我展示的

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)

第 156-158 行
1907-1931/com.example.casquejo.loginadmin E/AndroidRuntime:致命异常:AsyncTask #2 进程:com.example.casquejo.loginadmin,PID:1907 java.lang.RuntimeException:执行 doInBackground 时发生错误() 引起:在 com.example.casquejo.loginadmin.NewProductActivity$CreateNewProduct.doInBackground(NewProductActivity.java:58) 处的 java.lang.NullPointerException atcom.example.casquejo.loginadmin.NewProductActivity$CreateNewProduct.doInBackground(NewProductActivity.java:85) ) 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

有人可以帮我解决这个问题,或者有人可以提供一个想法如何解决这个问题`下面是我的 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();
        }

    }
}

回答by Blackbelt

the ide is referring to

ide是指

  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 onClickand pass the values through execute(). E.g.

读取值应该不成问题,但为了摆脱此警告/错误,您可以将其移入onClick并通过execute(). 例如

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 doInBackgroundis 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,

doInBackground被调用时,您可以通过前面的参数读取那些 bac,String... args. 三个点结构保留用于可变参数,并且可变参数可以像数组一样使用[]符号进行访问。在这个例子的情况下,

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

args[0]包含 的值nameargs[1]包含 的值priceargs[2]包含 的值description

回答by Simas

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

您正在getText()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 SaveProductDetailsdoInBackgroundmethod:

SaveProductDetailsdoInBackground方法内部:

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

回答by rcbevans

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.

在异步任务中,该doInBackground(...)方法在后台(非 UI)线程中运行。正如您在给出的错误中看到的那样,不允许您从后台线程与 UI 元素进行交互。

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

您可以按照其他答案之一的建议将参数传递到后台线程,或者您可以修改异步任务,以便onPreExecute()在 UI 线程上执行的方法中读取 UI 字符串值(onPostExecute()方法也是)。

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 thisone to understand more about AsyncTasks, how they work, how to use them including details such as which method runs on which thread.

我建议考虑看看一个博客帖子如一个更多地了解AsyncTasks,它们是如何工作,如何使用它们,包括细节,比如哪些方法运行在哪个线程。

回答by VIjay J

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:

您可以从 Worker Thread阅读在 UI 线程上使用变量
在您的问题中,您正试图从后台线程访问 TextView 的文本。为了保持一致,您不应该这样做,因为它们可能是主线程(UI 线程同时设置 TextView)的可能性。为了避免这样的风景,你可以这样做:

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
} 

回答by Millu

You do not need to pass the value into the execute method. Set the name, price and description variables as global. To get the value from EditTest on a button click code it like below:

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

Everytime you need to click on the button to get the JSON data.

每次您需要单击按钮以获取 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();
    }
});

Now name, price and description have its value whatever you entered.

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

Now your CreateNewProduct class seems like this:

现在你的 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();
    }

}

}