我正在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),却没有发现任何合理的答案。
答案 0 :(得分:0)
首先,从该线程解开代码。 setText()
已经是异步的,因此是多余的。要么使用Thread,要么使用AsyncTask。
第二件事,只能在 main 或UI线程上修改视图,例如EditText。在View上运行runOnUiThread(new Runnable() {
@Override
public void run() {
//appropriate setText()
}
});
或 any 其他方法时,它必须位于主线程上。
如果这是活动中的内容,则可以使用:
private Handler handler = new Handler(Looper.getMainLooper());
否则,您将需要使用处理程序。创建一个全局变量:
runOnUiThread()
,而不是使用handler.post()
,而是使用runOnUiThread
,并使用相同的语法(只需将handler.post
替换为onPostExecute()
)。
但是,还有第三件事。您实际上不应该在后台处理JSON字符串。您应该只在那时检索String。您的逻辑应该放在@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);
}
}
}
中,它已经为您在主线程上执行。
您的代码应如下所示:
{{1}}
答案 1 :(得分:0)
与任何UI元素(例如EditText)进行交互时,除了UI线程(或主线程)之外,您都不能使用其他任何东西。
换句话说,必须从UI线程更改UI元素。
您可以做什么:
移动将UI元素(如EditText)从doInBackground(String ... str)更新为onPostExecuted(String str)的代码。
每次使用另一个线程中的任何UI元素时,请使用View.post(Runnable runnable)方法。喜欢:
editText.post(
new Runnable() {
@Override
public void run() {
//do your work
}
}
);
或在活动中使用Activity.runOnUiThread(Runnable runnable)方法
runOnUiThread(
new Runnable() {
@Override
public void run() {
//do your work
}
}
);