在EditText中设置文本导致应用程序崩溃



我正在Android Studio中编程一个应用程序。我从服务器中获取json文件,然后将其提取为字符串,并希望在EditText中显示以使其可以修改。

这是我的代码

protected String doInBackground(String... atr) {
new Thread(new Runnable() {
public void run() {
int success;
try {
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("pid", pid));
params.add(new BasicNameValuePair("name", table_name));

JSONObject json = jsonParser.makeHttpRequest(url_product_details, "GET", params);
Log.d("Single Product Details", json.toString());
success = json.getInt(TAG_SUCCESS);
if (success == 1) {
JSONArray productObj = json.getJSONArray(TAG_PRODUCT);
JSONObject product = productObj.getJSONObject(0);
String _name = product.getString("name");
name.setText(_name, EditText.BufferType.EDITABLE);
if(!product.isNull("price")) {
Integer _price = product.getInt("price");
price.setText(_price, EditText.BufferType.EDITABLE);
}
if(!product.isNull("quantity")) {
Integer _quantity = product.getInt("quantity");
quantity.setText(_quantity, EditText.BufferType.EDITABLE);
}
if(!product.isNull("promotion")) {
Integer _promotion = product.getInt("promotion");
promotion.setText(_promotion, EditText.BufferType.EDITABLE);
}
} else {
Intent i = new Intent(getApplicationContext(), AllProductsActivity.class);
i.putExtra(TAG_PID, pid);
i.putExtra("list_name", table_name);
startActivity(i);
finish();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}).start();
return null;
}

不幸的是,当我尝试这样做时,当我试图上传文本到EditText时,这个应用程序崩溃了。我确认EditText不是null,字符串也是。没有任何错误信息阻碍了这个问题。有人知道吗?我到处找(也许我找不到xD(,没有找到任何合理的东西。

首先,从该线程中打开代码。doInBackground()已经是异步的,所以它是多余的。使用Thread或AsyncTask,而不是两者都使用。

其次,视图(如EditText(只能在main或UI线程上修改。当您在View上运行setText()任何其他方法时,它需要在主线程上。

如果这是在活动中,您可以使用:

runOnUiThread(new Runnable() {
@Override
public void run() {
//appropriate setText()
}
});

否则,您将需要使用一个处理程序。创建全局变量:

private Handler handler = new Handler(Looper.getMainLooper());

而不是使用runOnUiThread(),而是使用具有相同语法的handler.post()(只需将runOnUiThread替换为handler.post(。

然而,还有第三件事。您不应该在后台处理JSON字符串。您应该只在此时检索字符串。您的逻辑应该进入onPostExecute(),它已经在主线程上为您执行了。

你的代码应该是这样的:

@Override
protected String doInBackground(String... atr) {
try {
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("pid", pid));
params.add(new BasicNameValuePair("name", table_name));
JSONObject json = jsonParser.makeHttpRequest(url_product_details, "GET", params);
Log.d("Single Product Details", json.toString());
int success = json.getInt(TAG_SUCCESS);
if (success == 1) {
return json; //return the JSON String on success
} else {
Intent i = new Intent(getApplicationContext(), AllProductsActivity.class);
i.putExtra(TAG_PID, pid);
i.putExtra("list_name", table_name);
startActivity(i);
finish();
}
} catch (JSONException e) {
e.printStackTrace();
}
return null; //return null for any other result
}
@Override
protected void onPostExecute(String result) {
if (result != null) { //make sure result isn't null
JSONArray productObj = result.getJSONArray(TAG_PRODUCT);
JSONObject product = productObj.getJSONObject(0);
String _name = product.getString("name");
name.setText(_name, EditText.BufferType.EDITABLE);
if (!product.isNull("price")) {
Integer _price = product.getInt("price");
price.setText(_price, EditText.BufferType.EDITABLE);
}
if (!product.isNull("quantity")) {
Integer _quantity = product.getInt("quantity");
quantity.setText(_quantity, EditText.BufferType.EDITABLE);
}
if (!product.isNull("promotion")) {
Integer _promotion = product.getInt("promotion");
promotion.setText(_promotion, EditText.BufferType.EDITABLE);
}
}
}

当您与任何UI元素(如EditText(交互时,您不能使用UI线程(或主线程(以外的任何东西。

换句话说,必须从UI线程更改UI元素。

你能做什么:

  1. 将UI元素(如EditText(更新的代码从doInBackground(String…str(移动到onPostExecuted(String str(。

  2. 每次使用其他线程中的任何UI元素时,请使用View.post(Runnablerunnable(方法。类似:

    editText.post(
    new Runnable() {
    @Override
    public void run() {
    //do your work
    }
    }
    );
    

    或者在活动中使用Activity.runOnUiThread(可运行(方法

    runOnUiThread(
    new Runnable() {
    @Override
    public void run() {
    //do your work
    }
    }
    );
    

最新更新