如何创建asyncTask以防止networkOnMainThreadException

时间:2012-10-12 05:43:48

标签: android tcp android-asynctask

我是Android应用程序开发的新手。我试图开发一个Android服务器客户端聊天

我的第一个项目。这是客户端的代码。当客户按btnJoin时,

它将连接到服务器并发送一个字符串。我读了很多例子,其中很多都是

看起来像这样。我得到了networkOnMainThreadException。如何制作asyncTask以防止

这个问题?任何帮助将不胜感激。

btnJoin = (Button) findViewById(R.id.buttonJoin);
btnJoin.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
        Socket socket = null;
        DataOutputStream dataOutputStream = null;
        DataInputStream dataInputStream = null;
        try {
            socket = new Socket("192.168.1.4", 9092);
            dataOutputStream = new DataOutputStream(socket.getOutputStream());
            dataInputStream = new DataInputStream(socket.getInputStream());
            dataOutputStream.writeUTF("Hello server!");
            txtIP.append(dataInputStream.readUTF() + "\n");
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (socket != null) {
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (dataOutputStream != null) {
                try {
                    dataOutputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (dataInputStream != null) {
                try {
                    dataInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
});

4 个答案:

答案 0 :(得分:2)

将您的代码更改为:

   btnJoin.setOnClickListener(new OnClickListener() {
    @Override
   public void onClick(View view){

              new LongOperation().execute("");

    }
}

private class LongOperation extends AsyncTask<String, Void, String> {
     Socket socket = null;
     String strresult="";
        DataOutputStream dataOutputStream = null;
        DataInputStream dataInputStream = null;
          @Override
          protected String doInBackground(String... params) {

        try {
            socket = new Socket("192.168.1.4", 9092);
            dataOutputStream = new DataOutputStream(socket.getOutputStream());
            dataInputStream = new DataInputStream(socket.getInputStream());
            dataOutputStream.writeUTF("Hello server!");
            strresult.append(dataInputStream.readUTF() + "\n");
         //   txtIP.append(dataInputStream.readUTF() + "\n");
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (socket != null) {
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (dataOutputStream != null) {
                try {
                    dataOutputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (dataInputStream != null) {
                try {
                    dataInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

                return strresult;
          }      

          @Override
          protected void onPostExecute(String result) {
                TextView txtIP= (TextView) findViewById(R.id.txtIP);
              //  txtIP.append(result + "\n");
                txtIP.setText(result + "\n");

          }

          @Override
          protected void onPreExecute() {
          }

    }  

答案 1 :(得分:1)

像这样使用AsyncTask:

首先将它嵌套在你的类中,它看起来应该类似于:

private class Communicator extends AsyncTask<Void, Void, Boolean> {
    String tmp;
    String err;

    @Override
    protected Boolean doInBackground() {

        try {
                socket = new Socket("192.168.1.4", 9092);
                dataOutputStream = new DataOutputStream(socket.getOutputStream());
                dataInputStream = new DataInputStream(socket.getInputStream());
                dataOutputStream.writeUTF("Hello server!");


         } catch (UnknownHostException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (socket != null) {
                    try {
                        socket.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (dataOutputStream != null) {
                    try {
                        dataOutputStream.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (dataInputStream != null) {
                    try {
                        dataInputStream.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }

        return true;
    }

    @Override
    protected void onPreExecute() {

    }

    @Override
    protected void onPostExecute(Boolean result) {
         txtIP.append(dataInputStream.readUTF() + "\n");            


    }
}

当你有AsyncTask时,你可以这样开始:

...
@Override
public void onClick(View v) {
Communicator c=new Communicator();
c.execute();
}
....

答案 2 :(得分:0)

尝试在您的应用中实现此代码

private class LongOperation extends AsyncTask<Object, Integer, Object> {

        @Override
        protected void onPreExecute() {



            super.onPreExecute();
        }

        @Override
        protected Object doInBackground(Object... params) {
            //do hard work here
                                return params;
        }

        @Override
        protected void onProgressUpdate(Integer... values) {


        }

        @Override
        protected void onPostExecute(Object result) {



            super.onPostExecute(result);
        }
    } 

答案 3 :(得分:0)

AsyncTask必须是子类才能使用。子类将覆盖至少一个方法(doInBackground(Params ...)),并且通常会覆盖第二个方法(onPostExecute(Result)。)

以下是子类化的示例

private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
     protected Long doInBackground(URL... urls) {
         int count = urls.length;
         long totalSize = 0;
         for (int i = 0; i < count; i++) {
             totalSize += Downloader.downloadFile(urls[i]);
             publishProgress((int) ((i / (float) count) * 100));
             // Escape early if cancel() is called
             if (isCancelled()) break;
         }
         return totalSize;
     }

     protected void onProgressUpdate(Integer... progress) {
         setProgressPercent(progress[0]);
     }

     protected void onPostExecute(Long result) {
         showDialog("Downloaded " + result + " bytes");
     }
 }

创建后,任务执行非常简单:

 new DownloadFilesTask().execute(url1, url2, url3);

有关详细信息,请参阅以下链接...

http://www.vogella.com/articles/AndroidPerformance/article.html

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