简体   繁体   English

android.os.NetworkOnMainThreadException错误,即使在AsyncTask中运行

[英]android.os.NetworkOnMainThreadException error even when running in AsyncTask

i am getting the android.os.NetworkOnMainThreadException error when i try to connect to the internet.I know that the later versions of android(HoneyComb onwards) do not allow you to perform network IO on the UI thread that's why i am using the AsyncTask.no errors on the code but when it runs,i get the android.os.NetworkOnMainThreadException error the code: 当我尝试连接到Internet时出现android.os.NetworkOnMainThreadException错误。我知道更高版本的android(HoneyComb及更高版本)不允许您在UI线程上执行网络IO,这就是为什么我使用AsyncTask的原因.no代码上没有错误,但是当它运行时,我得到了android.os.NetworkOnMainThreadException错误代码:

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.mainactivity);
    new GetProductDetails().execute();
}

class GetProductDetails extends AsyncTask<String, String, String> {

    /**
     * Before starting background thread Show Progress Dialog
     * */
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        pDialog = new ProgressDialog(MainActivity.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("pid", pid));

                    // getting product details by making HTTP request
                    // Note that product details url will use GET request
                    JSONObject json = jsonParser.makeHttpRequest(
                            url_product_details, "GET", params);

                    // check your log for json response
                    Log.d("Single Product Details", json.toString());

                    // json success tag
                    success = json.getInt(TAG_SUCCESS);
                    if (success == 1) {
                        // successfully received product details
                        JSONArray productObj = json
                                .getJSONArray(TAG_PRODUCT); // JSON Array

                        // get first product object from JSON Array
                        JSONObject product = productObj.getJSONObject(0);


                        txtName = (EditText) findViewById(R.id.inputName);
                        txtPrice = (EditText) findViewById(R.id.inputPrice);
                        txtDesc = (EditText) findViewById(R.id.inputDesc);

                        // display product data in EditText
                        txtName.setText(product.getString(TAG_NAME));
                        txtPrice.setText(product.getString(TAG_PRICE));
                        txtDesc.setText(product.getString(TAG_DESCRIPTION));


                    }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();
    }
}

i have read that a possible solution to this is using the StrictMode Policy but i am a bit reluctant to use this because it is recommended in development environments only.what's the problem here? 我已经读到一个可能的解决方案是使用StrictMode策略,但是我有点不愿意使用它,因为仅在开发环境中才建议使用它。这是什么问题?

What's the problem here? 这是什么问题

You are doing network I/O on the main application thread, from inside the Runnable you are using with runOnUiThread() . 您正在与runOnUiThread()一起使用的Runnable内部,在主应用程序线程上执行网络I / O。

Get rid of the runOnUiThread() and Runnable . 摆脱runOnUiThread()Runnable Put the networking code in doInBackground() . 将网络代码放入doInBackground() Update your widgets in onPostExecute() . onPostExecute()更新您的小部件。 You pass data from doInBackground() to onPostExecute() either by the return value from doInBackground() (which becomes the parameter passed to onPostExecute() ) or data members inside of the AsyncTask itself. 从传递数据doInBackground()onPostExecute()或者通过从返回值doInBackground()其变成传递给参数onPostExecute()的内部或数据成员AsyncTask本身。

You are using AsyncTask but in doInBackground you are calling 您正在使用AsyncTask,但是在doInBackground中您正在调用

// updating UI from Background Thread
        runOnUiThread(new Runnable() {
            public void run() {

In these strings you run all next code from doInBackground in main UI thread and it removes all AsyncTask effect. 在这些字符串中,您将在主UI线程中从doInBackground运行所有下一个代码,它将删除所有AsyncTask效果。

Than you run 比你跑

JSONObject json = jsonParser.makeHttpRequest(
                            url_product_details, "GET", params);

and it runs in main thread, as I described below. 并在主线程中运行,如下所述。 So, it throws the exception. 因此,它引发异常。

Move all your network code out of Runnable and put your Runnable at the end of doInBackground with only updates of widgets - it should works. 将所有网络代码移出Runnable,并将您的Runnable放在doInBackground的末尾,并且只更新小部件-它应该可以工作。

You are running network related operation on the ui thread. 您正在ui线程上运行与网络相关的操作。

You are using runOnUiThread inside doInbackground() . 您正在doInbackground()内部使用runOnUiThread Inside runOnUiThread you have the below runOnUiThread您具有以下内容

JSONObject json = jsonParser.makeHttpRequest(
                        url_product_details, "GET", params);

This causes NetworkOnMainThreadException . 这将导致NetworkOnMainThreadException

You are also missing @Override Annotation for doInBackground() and onPostExecute() . 您还缺少@Override注释的doInBackground()onPostExecute()

A can make the json request in doInbackground() and update ui in onPostExecute() . A可以使在JSON请求doInbackground()和在更新用户界面onPostExecute()

If you use runOnUiThread use it to update ui and move all network related operation in doInbackground . 如果您使用runOnUiThread使用它来更新ui并在doInbackground移动所有与网络相关的操作。

You can also move the below to onCreate . 您也可以将以下内容移至onCreate

  txtName = (EditText) findViewById(R.id.inputName);
  txtPrice = (EditText) findViewById(R.id.inputPrice);
  txtDesc = (EditText) findViewById(R.id.inputDesc);

Return the result of background computation in doInbackground . 返回doInbackground中背景计算的结果。 The result of doInbackground is a parameter to onPostExecute. doInbackground的结果是onPostExecute的参数。 You can use the same to update ui in onPostExecute . 您可以使用相同的方法在onPostExecute更新ui。

For more info check the docs 有关更多信息,请检查文档

http://developer.android.com/reference/android/os/AsyncTask.html http://developer.android.com/reference/android/os/AsyncTask.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM