使用asynctask进行网络连接

时间:2012-12-03 12:53:09

标签: java android sockets tcp android-asynctask

我正在尝试将asynctask合并到我的代码中,因为NetworkOnMainThreadException因为我在一分钟内收到了力量。

我已经完成了一些教程,但我仍然无法理解它。每次我尝试一下,我都会在整个地方遇到错误。

我看过的教程:

  1. [http://developer.android.com/reference/android/os/AsyncTask.html] [1]
  2. [https://androidresearch.wordpress.com/2012/03/17/understanding-asynctask-once-and-forever/] [2]
  3. 基本上代码的作用是:

    1. 从意图中获取IP地址。
    2. 使用端口32连接到IP
    3. 然后发送命令,等待响应并发送另一个命令。
    4. 在我发送的2个命令之后,我应该收到" SNX_COM>"
    5. 的回复
    6. 建立连接后,我希望连接保持打开状态,以便在按钮单击时发送特定命令。
    7. ^^这基本上是我的代码应该实现的目标^^

      package com.smarte.smartipcontrol;
      
      import java.io.BufferedReader;
      import java.io.BufferedWriter;
      import java.io.IOException;
      import java.io.InputStreamReader;
      import java.io.OutputStreamWriter;
      import java.io.PrintWriter;
      import java.net.InetAddress;
      import java.net.Socket;
      import java.net.UnknownHostException;
      
      import android.app.Activity;
      import android.os.AsyncTask;
      import android.os.Bundle;
      import android.view.View;
      
      public class IPControl extends Activity {
      
      private Socket socket;
      private String serverIpAddress = "com.smarte.smartipcontrol.ACTU_IP";
      private static final int REDIRECTED_SERVERPORT = 32;
      public PrintWriter out;
      public BufferedReader in;
      public String data;
      public Object pd;
      
      
      
      public void getModel(View view) {
          try {
              out.println("[m\r\n");
              //System.out.print("root\r\n");
              while(!in.ready());
              String textStatus = readBuffer();
      
          } catch(IOException e) {}
      }
      
      
      @Override
      public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
      
         setContentView(R.layout.act_ipcontrol);
      
      
         try{   
      
          new AsyncAction().execute();
      
         }catch (Exception e) {
             e.printStackTrace();
         }
      
         }
      
      
      
      private class AsyncAction extends AsyncTask<String, Void, String> {
         protected String doInBackground(String... args) { 
         try {
       InetAddress serverAddr = InetAddress.getByName(serverIpAddress);
       socket = new Socket(serverAddr, REDIRECTED_SERVERPORT);
      } catch (UnknownHostException e1) {
       e1.printStackTrace();
      } catch (IOException e1) {
       e1.printStackTrace();
      }
      try {
       out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true); in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
       while (! in .ready());
       readBuffer();
       out.println("root\r\n");
       //System.out.print("root\r\n");
       while (! in .ready());
       readBuffer();
       out.println("root\r\n");
       //System.out.print("root\r\n");
       while (! in .ready());
       String msg = "";
      
      while ( in .ready()) {
       msg = msg + (char) in .read();
      }
      } catch (IOException e) {}
      
             return null;//returns what you want to pass to the onPostExecute()
         }
      
         protected void onPostExecute(String result) {
      
         //results the data returned from doInbackground
      
             IPControl.this.data = result;
      
      
      
             }
         }
      
      
      private String readBuffer() throws IOException {
          String msg = "";
      
          while(in.ready()) {
              msg = msg + (char)in.read();
          }
          //System.out.print(msg);
          if(msg.indexOf("SNX_COM> ") != -1) return msg.substring(0, msg.indexOf("SNX_COM> "));
          else return msg;
      }
      
      }
      

      logcat的

      12-03 15:39:56.346: E/AndroidRuntime(2697): FATAL EXCEPTION: AsyncTask #5
      12-03 15:39:56.346: E/AndroidRuntime(2697): java.lang.RuntimeException: An error occured while executing doInBackground()
      12-03 15:39:56.346: E/AndroidRuntime(2697):     at android.os.AsyncTask$3.done(AsyncTask.java:299)
      12-03 15:39:56.346: E/AndroidRuntime(2697):     at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:352)
      12-03 15:39:56.346: E/AndroidRuntime(2697):     at java.util.concurrent.FutureTask.setException(FutureTask.java:219)
      12-03 15:39:56.346: E/AndroidRuntime(2697):     at java.util.concurrent.FutureTask.run(FutureTask.java:239)
      12-03 15:39:56.346: E/AndroidRuntime(2697):     at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
      12-03 15:39:56.346: E/AndroidRuntime(2697):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
      12-03 15:39:56.346: E/AndroidRuntime(2697):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
      12-03 15:39:56.346: E/AndroidRuntime(2697):     at java.lang.Thread.run(Thread.java:856)
      12-03 15:39:56.346: E/AndroidRuntime(2697): Caused by: java.lang.NullPointerException
      12-03 15:39:56.346: E/AndroidRuntime(2697):     at com.smarte.smartipcontrol.IPControl$AsyncAction.doInBackground(IPControl.java:71)
      12-03 15:39:56.346: E/AndroidRuntime(2697):     at com.smarte.smartipcontrol.IPControl$AsyncAction.doInBackground(IPControl.java:1)
      12-03 15:39:56.346: E/AndroidRuntime(2697):     at android.os.AsyncTask$2.call(AsyncTask.java:287)
      12-03 15:39:56.346: E/AndroidRuntime(2697):     at java.util.concurrent.FutureTask.run(FutureTask.java:234)
      12-03 15:39:56.346: E/AndroidRuntime(2697):     ... 4 more
      

2 个答案:

答案 0 :(得分:1)

您必须将您的createConnection();移动到您的asynctask doInBackground(),您必须将其添加为项目的内部类或单独的类 例如:

 private class DownloadFilesTask extends AsyncTask<Void, Void, Void> {
 protected Void doInBackground(Param[]...) {
     createConnection();
 }

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

 protected void onPostExecute() {


 }

}

这是您提供的第一个链接,我刚刚更改了一下。确保从方法createConnection()返回一些内容,以便您知道asynctask已成功完成,并相应地更改DownloadFilesTask,以便doInBackground()onPostExecute()返回相同的类型

答案 1 :(得分:1)

  

建立连接后,我希望连接保持打开状态,以便在点击按钮时发送特定命令。

如果要将命令发送到服务器,可能必须创建一个新线程:

button.setOnClickListener(new OnClickListener()
{
    public void onClick(View arg0)
    {
      new Thread()
      {
        @Override
        public void run()
        {
          methods.sendCommandToServer();
        } 
      }.start(); 
     } 
  });