【问题标题】:How to create asyncTask to prevent networkOnMainThreadException如何创建 asyncTask 以防止 networkOnMainThreadException
【发布时间】:2012-10-02 21:47:53
【问题描述】:

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

【问题讨论】:

  • @avd 感谢您编辑我的问题。我会正确地格式化我的下一个问题。 :D

标签: android tcp android-asynctask


【解决方案1】:

将代码更改为:

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

    }  

【讨论】:

  • 感谢您的回复。我按照你的代码,它似乎工作。我在 void onPostExecute 上添加了一行。 Log.d("OnPostExecute","完成")。但是日志永远不会出现。有什么线索吗?
  • 尝试 System.out.println("OnPostExecute ,Done");之前 TextView txtIP= (TextView) findViewById(R.id.txtIP);在 txtIP.setText(result + "\n"); 之后在这两个地方
  • 第一个 println 触发,第二个 println 不触发。没关系,数据总是成功发送。谢谢你的建议。非常感谢您的帮助。
【解决方案2】:

像这样使用 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();
}
....

【讨论】:

  • txtIP.append(dataInputStream.readUTF() + "\n");不会在 doInBackground() 中工作
  • txtIP.append(dataInputStream.readUTF() + "\n");无法从 doInBackground() 访问
  • 感谢您的回复。但是您的解决方案似乎有问题。真的很感激。
【解决方案3】:

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

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

【讨论】:

    【解决方案4】:

    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

    【讨论】:

      猜你喜欢
      • 2013-11-11
      • 2012-11-16
      • 2015-01-01
      • 2012-12-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-11
      • 1970-01-01
      相关资源
      最近更新 更多