我的 Android 项目中有一个名为 EditTrip_Activity.java 的类/Activity ,并且我不断收到此 NetworkOnMainThreadException。我之前已经得到过这个问题,并通过将代码放入 AsyncTask 的 doInBackground() 中来修复它。我在这里做了类似的事情,但它似乎不起作用,我不知道为什么......
EditTrip_Activity.java
public class EditTrip_Activity extends Activity {
EditText txtTripName;
EditText txtStartLoc;
EditText txtEndLoc;
EditText txtDistTravelled;
EditText txtCreatedAt;
Button btnSave;
Button btnDelete;
String tripid;
// Progress Dialog
private ProgressDialog pDialog;
// JSON parser class
JSONParser_Helpers2 jsonParser = new JSONParser_Helpers2();
// single product url
private static final String url_product_details = "http://10.0.2.2/android_connect/get_product_details.php";
// url to update product
private static final String url_update_product = "http://10.0.2.2/android_connect/update_product.php";
// url to delete product
private static final String url_delete_product = "http://10.0.2.2/android_connect/delete_product.php";
// JSON Node names
private static final String TAG_SUCCESS = "success";
private static final String TAG_TRIPS = "trips";
private static final String TAG_TRIPID = "tripid";
private static final String TAG_TRIPNAME = "tripName";
private static final String TAG_STARTINGLOCATION = "startingLoc";
private static final String TAG_ENDINGLOCATION = "endingLoc";
private static final String TAG_DISTANCETRAVELLED = "distanceTravelled";
private static final String TAG_CREATEDAT = "date";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.edit_trip);
// save button
btnSave = (Button) findViewById(R.id.btnSave);
btnDelete = (Button) findViewById(R.id.btnDelete);
// getting product details from intent
Intent i = getIntent();
// getting product id (pid) from intent
tripid = i.getStringExtra(TAG_TRIPID);
// Getting complete product details in background thread
new GetProductDetails().execute();
// save button click event
btnSave.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
// starting background task to update product
new SaveProductDetails().execute();
}
});
// Delete button click event
btnDelete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
// deleting product in background thread
new DeleteProduct().execute();
}
});
//enable app icon as the up button to go back to previous screen as outlined in manifest xml
getActionBar().setDisplayHomeAsUpEnabled(true);
}
/**
* Background Async Task to Get complete product details
* */
class GetProductDetails extends AsyncTask<String, String, String> {
/**
* Before starting background thread Show Progress Dialog
* */
@Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(EditTrip_Activity.this);
pDialog.setMessage("Loading product details. Please wait...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(true);
pDialog.show();
}
/**
* Getting product details in background thread
* */
protected String doInBackground(String... params) {
// updating UI from Background Thread
runOnUiThread(new Runnable() {
public void run() {
// Check for success tag
int success;
try {
// Building Parameters
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("tripid", tripid));
// getting product details by making HTTP request
// Note that product details url will use GET request
JSONObject json = jsonParser.makeHttpRequest(
url_trip_details, "GET", params);
// check your log for json response
Log.d("Single Trip Details", json.toString());
// json success tag
success = json.getInt(TAG_SUCCESS);
if (success == 1) {
// successfully received product details
JSONArray productObj = json
.getJSONArray(TAG_TRIPS); // JSON Array
// get first product object from JSON Array
JSONObject product = productObj.getJSONObject(0);
// product with this pid found
// Edit Text
EditText txtTripName = (EditText) findViewById(R.id.inputName);
EditText txtStartLoc = (EditText) findViewById(R.id.inputStartLoc);
EditText txtEndLoc = (EditText) findViewById(R.id.inputEndLoc);
EditText txtDistTravelled = (EditText) findViewById(R.id.inputDistTravelled);
EditText txtCreatedAt = (EditText) findViewById(R.id.inputCreatedAt);
// display product data in EditText
txtTripName.setText(product.getString(TAG_TRIPNAME));
txtStartLoc.setText(product.getString(TAG_STARTINGLOCATION));
txtEndLoc.setText(product.getString(TAG_ENDINGLOCATION));
txtDistTravelled.setText(product.getString(TAG_DISTANCETRAVELLED));
txtCreatedAt.setText(product.getString(TAG_CREATEDAT));
}else{
// product with pid not found
}
} catch (JSONException e) {
e.printStackTrace();
}
}
});
return null;
}
/**
* After completing background task Dismiss the progress dialog
* **/
protected void onPostExecute(String file_url) {
// dismiss the dialog once got all details
pDialog.dismiss();
}
}
其他异步任务中还有更多此类,但这是引发错误的地方。知道问题出在哪里吗?
这是 LogCat:
01-23 21:20:41.024: E/AndroidRuntime(913): FATAL EXCEPTION: main
01-23 21:20:41.024: E/AndroidRuntime(913): android.os.NetworkOnMainThreadException
01-23 21:20:41.024: E/AndroidRuntime(913): at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1133)
01-23 21:20:41.024: E/AndroidRuntime(913): at java.net.InetAddress.lookupHostByName(InetAddress.java:385)
01-23 21:20:41.024: E/AndroidRuntime(913): at java.net.InetAddress.getAllByNameImpl(InetAddress.java:236)
01-23 21:20:41.024: E/AndroidRuntime(913): at java.net.InetAddress.getAllByName(InetAddress.java:214)
01-23 21:20:41.024: E/AndroidRuntime(913): at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:137)
01-23 21:20:41.024: E/AndroidRuntime(913): at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
01-23 21:20:41.024: E/AndroidRuntime(913): at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
01-23 21:20:41.024: E/AndroidRuntime(913): at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:360)
01-23 21:20:41.024: E/AndroidRuntime(913): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)
01-23 21:20:41.024: E/AndroidRuntime(913): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
01-23 21:20:41.024: E/AndroidRuntime(913): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465)
01-23 21:20:41.024: E/AndroidRuntime(913): at com.autotracker.activities.JSONParser_Helpers2.makeHttpRequest(JSONParser_Helpers2.java:71)
01-23 21:20:41.024: E/AndroidRuntime(913): at com.autotracker.activities.EditTrip_Activity$GetProductDetails$1.run(EditTrip_Activity.java:148)
01-23 21:20:41.024: E/AndroidRuntime(913): at android.os.Handler.handleCallback(Handler.java:730)
01-23 21:20:41.024: E/AndroidRuntime(913): at android.os.Handler.dispatchMessage(Handler.java:92)
01-23 21:20:41.024: E/AndroidRuntime(913): at android.os.Looper.loop(Looper.java:137)
01-23 21:20:41.024: E/AndroidRuntime(913): at android.app.ActivityThread.main(ActivityThread.java:5103)
01-23 21:20:41.024: E/AndroidRuntime(913): at java.lang.reflect.Method.invokeNative(Native Method)
01-23 21:20:41.024: E/AndroidRuntime(913): at java.lang.reflect.Method.invoke(Method.java:525)
01-23 21:20:41.024: E/AndroidRuntime(913): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
01-23 21:20:41.024: E/AndroidRuntime(913): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
01-23 21:20:41.024: E/AndroidRuntime(913): at dalvik.system.NativeStart.main(Native Method)
编辑:
class GetProductDetails extends AsyncTask<String, String, JSONObject> {
/**
* Before starting background thread Show Progress Dialog
* */
@Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(EditTrip_Activity.this);
pDialog.setMessage("Loading product details. Please wait...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(true);
pDialog.show();
// Edit Text
txtTripName = (EditText) findViewById(R.id.inputTrip);
txtStartLoc = (EditText) findViewById(R.id.inputStartLoc);
txtEndLoc = (EditText) findViewById(R.id.inputEndLoc);
txtDistTravelled = (EditText) findViewById(R.id.inputDistTravelled);
txtCreatedAt = (EditText) findViewById(R.id.inputCreatedAt);
}
/**
* Getting product details in background thread
* */
protected JSONObject doInBackground(String... params) {
JSONObject product = null;
// Check for success tag
int success;
try {
// Building Parameters
List<NameValuePair> params1 = new ArrayList<NameValuePair>();
params1.add(new BasicNameValuePair("tripid", tripid));
// getting product details by making HTTP request
// Note that product details url will use GET request
JSONObject json = jsonParser.makeHttpRequest(
url_trip_details, "GET", params1);
// check your log for json response
Log.d("Single Trip Details", json.toString());
// json success tag
success = json.getInt(TAG_SUCCESS);
if (success == 1) {
// successfully received product details
JSONArray productObj = json.getJSONArray(TAG_TRIPS); // JSON Array
// get first product object from JSON Array
product = productObj.getJSONObject(0);
}else{
// product with pid not found
}
} catch (JSONException e) {
e.printStackTrace();
}
return product;
}
/**
* After completing background task Dismiss the progress dialog
* **/
protected void onPostExecute(JSONObject product) {
// dismiss the dialog once got all details
pDialog.dismiss();
try {
// display product data in EditText
txtTripName.setText(product.getString(TAG_TRIPNAME));
txtStartLoc.setText(product.getString(TAG_STARTINGLOCATION));
txtEndLoc.setText(product.getString(TAG_ENDINGLOCATION));
txtDistTravelled.setText(product.getString(TAG_DISTANCETRAVELLED));
txtCreatedAt.setText(product.getString(TAG_CREATEDAT));
} catch (JSONException e) {
e.printStackTrace();
}
}
}
已修复!
原来问题出在 findViewById(R.id.inputName) 这行,它应该是 inputTrip。现在一切都解决了。谢谢大家的帮助!
最佳答案
您在 doInBackground() 方法中通过 runOnUiThread() 与几乎所有的 AsyncTask
相矛盾。 AsyncTask 的目的是通过在单独的后台线程中运行来避免阻塞 UiThread,并且还能够使用 preExecute() 和 postexecute() 更新 UI。
编辑我将遵循这个总体轮廓并在您的 AsyncTask 中创建字段(很抱歉缺乏详细信息,从移动设备输入):
AsyncTask {
// Declare fields so you can access from all methods within class if needed
TextView tvProdDetail1, tvProdDetail2;
String prodDet1, prodDetail2;
preExecute(){
// Initialize field variables
tvProdDetail1 = (TextView) findViewById(R.id.my_tv_1);
tvProdDetail2 = (TextView) findViewById(R.id. my_tv_2);
}
doInBackground() {
/Do network operations in background, set strings prodDetail1 and prodDetail2 to values retrieved from net
}
post execute() {
// set text() to TextViews
tvProdDetail1.set text(prodDetail1);
tvProdDetail2.set text(prodDetail2);
}
}
希望这有助于您解决问题,祝您编码愉快!
关于java - NetworkOnMainThreadException 问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21323353/