我的Android项目中有一个名为EditTrip_Activity.java的类/活动,我不断收到此NetworkOnMainThreadException。我之前已经得到了这个并通过将我的代码放在AsyncTask的doInBackground()中来修复它。我在这里做了类似的事情,但似乎没有用,我不知道为什么......
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。现在一切都是固定的。谢谢你的帮助!
答案 0 :(得分:2)
通过在runOnUiThread()
方法中使用doInBackground()
,您实际上正在删除任何背景线程,因为所有内容都将在UI(主)线程上运行,这将引发{{ 1}}。
要解决此问题,请至少删除
行NetworkOnMainThreadException
来自JSONObject json = jsonParser.makeHttpRequest(url_trip_details, "GET", params);
来电的,如果可以,最好更多。
答案 1 :(得分:2)
你在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);
}
}
希望这有助于为您解决问题,快乐编码!