【问题标题】:Android:NetworkOnMainThreadException error inside AsyncTaskAndroid:AsyncTask 中的 NetworkOnMainThreadException 错误
【发布时间】:2014-10-07 11:21:58
【问题描述】:

好的,所以我创建了一个扩展 AsycTask 的内部类,以便我的代码在 UI 线程中运行。但是我收到了这个错误,所以我认为这意味着我的 onPostExecute 的某些部分需要在 doInBackground 中完成,但是我无法弄清楚这是什么

public class asyncTask extends AsyncTask<String, Integer, String> {

        ProgressDialog dialog = new ProgressDialog(PetrolPriceActivity.this);

        @Override
           protected void onPreExecute() {
          dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
          dialog.setProgress(0);
          dialog.setMax(100);
          dialog.setMessage("loading...");
          dialog.show();
           }

         @Override
           protected String doInBackground(String...parmans){
                {

                    for(int i = 0; i < 100; i++){


                        publishProgress(1);
                        try {
                            Thread.sleep(100);
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }

                    }


                    String urlString = petrolPriceURL;
                    String result = "";
                    InputStream anInStream = null;
                    int response = -1;
                    URL url = null;

                    try {
                        url = new URL(urlString);
                    } catch (MalformedURLException e) {
                        // TODO Auto-generated catch block
                        return null;
                    }
                    URLConnection conn = null;
                    try {
                        conn = url.openConnection();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        return null;
                    }

                    // Check that the connection can be opened
                    if (!(conn instanceof HttpURLConnection))
                        try {
                            throw new IOException("Not an HTTP connection");
                        } catch (IOException e) {
                            // TODO Auto-generated catch block
                            return null;
                        }
                    try
                    {
                        // Open connection
                        HttpURLConnection httpConn = (HttpURLConnection) conn;
                        httpConn.setAllowUserInteraction(false);
                        httpConn.setInstanceFollowRedirects(true);
                        httpConn.setRequestMethod("GET");
                        httpConn.connect();
                        response = httpConn.getResponseCode();
                        // Check that connection is OK
                        if (response == HttpURLConnection.HTTP_OK)
                        {
                            // Connection is OK so open a reader 
                            anInStream = httpConn.getInputStream();
                            InputStreamReader in= new InputStreamReader(anInStream);
                            BufferedReader bin= new BufferedReader(in);

                            // Read in the data from the RSS stream
                            String line = new String();
                            while (( (line = bin.readLine())) != null)
                            {
                                result = result + "\n" + line;
                            }
                        }
                    }
                    catch (IOException ex)
                    {
                            try {
                                throw new IOException("Error connecting");
                            } catch (IOException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            }
                    }

            return result;

                }
           }
           @Override

           protected void onProgressUpdate(Integer...progress){

               dialog.incrementProgressBy(progress[0]);
           }

           @Override
           protected void onPostExecute(String result) {
               // Get the data from the RSS stream as a string

               errorText = (TextView)findViewById(R.id.error);
               response = (TextView)findViewById(R.id.title);

               try
                {
                    // Get the data from the RSS stream as a string
                    result =  doInBackground(petrolPriceURL);
                    response.setText(result);
                    Log.v(TAG, "index=" + result);
                }
                catch(Exception ae)
                {
                    // Handle error
                    errorText.setText("Error");
                    // Add error info to log for diagnostics
                    errorText.setText(ae.toString());
                } 
                if(dialog.getProgress() == dialog.getMax())
                dialog.dismiss();

           }
        }

如果有人能指出我的错误,并举例说明代码在我的 doInBackground 中的位置,那就太好了。谢谢

【问题讨论】:

    标签: java android exception android-asynctask networkonmainthread


    【解决方案1】:

    问题:

    result =  doInBackground(petrolPriceURL);
    

    您在onPostExecute 中隐式调用doInbackground 方法,该方法实际上将在您的UI 线程中运行,而不是在不同的线程上,从而导致Android:NetworkOnMainThreadException

    当你执行你的Asynctask时,也没有必要调用doInBackground,它已经在onPostExecute之前执行了。直接使用onPostExecuteresult参数即可。

    样本:

    @Override
           protected void onPostExecute(String result) {
               // Get the data from the RSS stream as a string
    
               errorText = (TextView)findViewById(R.id.error);
               response = (TextView)findViewById(R.id.title);
    
                response.setText(result);
    
                if(dialog.getProgress() == dialog.getMax())
                dialog.dismiss();
    
           }
    

    【讨论】:

    • 非常感谢我是 AsycTask 的新手,但我应该意识到这个错误。非常感谢您提供的代码示例
    【解决方案2】:

    我怀疑错误与您的这部分代码有关:

    try
     {
     // Get the data from the RSS stream as a string
     result =  doInBackground(petrolPriceURL);
     response.setText(result);
     Log.v(TAG, "index=" + result);
     }
    

    doInBackgound 会在您调用 asynctask.execute 时自动调用。要正确启动任务,您应该 (1) 创建任务的新实例; (2)在execute方法中传递doInBackground中需要使用的字符串参数; (3) 使用它们; (4)将结果返回给onPostExecute。

    例如:

     //in your activity or fragment
     MyTask postTask = new MyTask();
     postTask.execute(value1, value2, value3);
    
     //in your async task
     @Override
     protected String doInBackground(String... params){
    
          //extract values
          String value1 = params[0];
          String value2 = params[1];
          String value3 = params[2];
    
          // do some work and return result
          return value1 + value2;
     }
    
     @Override
     protected void onPostExecute(String result){
    
          //use the result you returned from you doInBackground method
     }
    

    您应该尝试在 doInBackground 方法中完成所有“工作”。 Reutrn 您要在主/UI 线程上使用的结果。这将自动作为参数传递给 onPostExecute 方法(在主/UI 线程上运行)。

    【讨论】:

    • 很好的答案,但是我实际上返回了值,这是一个愚蠢的错误,我在 onPostExecute 中再次访问 doInBackground 方法,这是完全没用的,因为无论如何我执行 asyncTask 时都会调用它。我看到了我的错误,但非常感谢您的回答
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-27
    • 1970-01-01
    • 2012-08-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多