0

当我尝试使用以下代码时,出现异常 android.os.NetworkOnMainThreadException:

public class CheckServer  extends Activity{

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        Runnable runn = null;
        HttpTask.execute(runn);



    }
    private class HttpTask extends AsyncTask<String, String, String>
    {

        @Override
        protected String doInBackground(String... params) {
            // TODO Auto-generated method stub
            HttpURLConnection urlConnection = null;

            URL theURL = null;
            try {
                theURL = new URL("http://192.168.2.8/parkme/Client/clientquery.php?ticket=66t");
            } catch (MalformedURLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            try {
                urlConnection = (HttpURLConnection) theURL.openConnection();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            String response = null;
            try {
                response = readInputStream(urlConnection.getInputStream());
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return response;

        }

        private String readInputStream(InputStream is) {
            // TODO Auto-generated method stub
            String line = "";
            StringBuilder total = new StringBuilder();
            BufferedReader rd = new BufferedReader(new InputStreamReader(is));
            try {
                while ((line = rd.readLine()) != null) {
                    total.append(line);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return total.toString();

        }
        @Override
        protected void onPostExecute(String result) {
            // TODO Auto-generated method stub
            Toast.makeText(getApplicationContext(), result, Toast.LENGTH_LONG).show();
        }
}}

如果可能的话,有人可以告诉我如何在异步任务中使用它并获得输出吗?我试过了,但似乎无处可去。

4

4 回答 4

2

好的,让我们一步一步来...

1)创建私有类扩展AsyncTask

private class HttpUrlConnectionTask extends AsyncTask {

2)覆盖doInBackground()方法,这将做繁重的负载

@Override
protected Object doInBackground(Object... params) {
// your HttpUrlConnection code goes here

return response;

3)一旦工作完成并返回,该onPostExecute()方法将被调用。该result参数包含 -sodoInBackground()响应的返回值。

@Override
protected void onPostExecute(Object result) {

在此方法中,您可以更新您的 UI。

4)最后让我们看看HttpUrlConnection代码

HttpURLConnection urlConnection = null;

URL theURL = new URL(url);
urlConnection = (HttpURLConnection) theURL.openConnection();
String response = readInputStream(urlConnection.getInputStream());
return response;

希望这可以帮助。快乐编码!

于 2013-04-04T20:58:49.680 回答
2

NetworkOnMainThread 发生异常是因为您在主 UI 线程上运行网络相关操作。这仅针对针对 Honeycomb SDK 或更高版本的应用程序抛出

您应该使用异步任务。

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

在 onCreate()

 new TheTask().execute();

您还可以将 url 等参数传递给 AsyncTask 的构造函数,并在 doInBackground() 中使用相同的参数

 class TheTask extends AsyncTask<Void,Void,Void>
 {
  protected void onPreExecute()
  {           super.onPreExecute();
            //display progressdialog.
  } 

   protected void doInBackground(Void ...params)//return result here
  {  
        //http request. do not update ui here

        return null;
  } 

   protected void onPostExecute(Void result)//result of doInBackground is passed a parameter
  {     
            super.onPostExecute(result);
            //dismiss progressdialog.
            //update ui using the result returned form doInbackground()

  } 

  }

当一个异步任务被执行时,任务会经过 4 个步骤:

  1. onPreExecute(),在任务执行之前在 UI 线程上调用。此步骤通常用于设置任务,例如通过在用户界面中显示进度条。

  2. doInBackground(Params...),在 onPreExecute() 完成执行后立即在后台线程上调用。此步骤用于执行可能需要很长时间的后台计算。异步任务的参数传递到这一步。计算的结果必须由这一步返回,并将传递回最后一步。此步骤还可以使用 publishProgress(Progress...) 来发布一个或多个进度单元。这些值在 UI 线程上的 onProgressUpdate(Progress...) 步骤中发布。

  3. onProgressUpdate(Progress...),在调用 publishProgress(Progress...) 后在 UI 线程上调用。执行的时间是不确定的。此方法用于在后台计算仍在执行时在用户界面中显示任何形式的进度。例如,它可用于动画进度条或在文本字段中显示日志。

  4. onPostExecute(Result),在后台计算完成后在 UI 线程上调用。后台计算的结果作为参数传递给该步骤。

于 2013-04-04T21:00:16.017 回答
-1

@Raghunandan 很好地解释了 AsyncTask 的工作原理

干得好:

public static class InitializeTask extends MyAsyncTask<String, String, String> {

private Activity activity;
private ProgressDialog dialog;

public InitializeTask(Activity activity) {
    this.activity = activity;
}

@Override
protected void onPostExecute(String result) {
        Toast.makeText(activity, result, Toast.LENGTH_SHORT).show();
}

@Override
protected String doInBackground(String... params) {
    HttpClient httpclient = new DefaultHttpClient();
    HttpGet httpget = new HttpGet("http://192.168.2.8/localhost/parkme/Client/clientquery.php?ticket=");
    try {
        HttpResponse response = httpclient.execute(httpget);
        if(response != null) {
            String line = "";
            InputStream inputstream = response.getEntity().getContent();
            return convertStreamToString(inputstream);
        } else {
            return "Unable to complete your request";
        }
    } catch (ClientProtocolException e) {
        return "Caught ClientProtocolException";
    } catch (IOException e) {
        return "Caught IOException";
    }
}

private String convertStreamToString(InputStream is) {
    String line = "";
    StringBuilder total = new StringBuilder();
    BufferedReader rd = new BufferedReader(new InputStreamReader(is));
    try {
        while ((line = rd.readLine()) != null) {
            total.append(line);
        }
    } catch (Exception e) {
        return "Stream Exception";
    }
    return total.toString();
}
}

附带一点说明,通常认为只捕获异常是错误的代码,因为它会捕获任何东西,而您没有考虑到它是什么。

要在 Activity 中使用 AsyncTask,请执行以下操作:

InitializeTask task = new InitializeTask(this)
task.execute()
于 2013-04-04T21:05:34.897 回答
-1

正如它所说的那样,在活动运行的线程上不允许网络活动。将代码移动到 Asynctask 是正确执行此操作的方法。虽然如果你只是想让你的概念仍然有效,你可以这样做......

//lazy workaround with newer than gingerbread
//normally UI thread can't get Internet.
if(Build.VERSION.SDK_INT >= 9){
    StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
    StrictMode.setThreadPolicy(policy);
}

然后UI线程实际上可以。但是,我不会发布这样的东西,我什至没有尝试过。这只是我经常使用的懒惰调试动作。

于 2013-04-04T21:08:36.223 回答