java - NetworkOnMainThreadException 问题?

标签 java android android-asynctask

我的 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/

相关文章:

java - 传输监听器和 ActiveMq 重新启动

Java 接口(interface) - 参数多态性

Android:为什么 MediaPlayer 播放的声音比 SoundPool 大?

android - 如何为从右到左的语言创建多语言 android 应用程序?

java - 调用 notifyDataSetChanged 后 Android ListView 未更新

java - 最多可容纳 N 个项目的 LIFO 数据结构

JavaFX超链接焦点矩形默认样式

java - Android Libgdx 致命信号 11(SIGSEGV),代码 1,故障地址 0x0

java - 刷新 android ListView 的最佳方法是什么?

Android AsyncTask vs 线程 + 处理程序 vs rxjava