java - 使用 asynctask 进行网络连接

标签 java android sockets tcp android-asynctask

由于 NetworkOnMainThreadException,我正在尝试将 asynctask 合并到我的代码中。

我已经学习了一些教程,但我仍然无法理解它。每次尝试时,我都会到处出错。

我看过的教程:

  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]

基本上代码的作用是:

  1. 从 Intent 中获取 IP 地址。
  2. 使用端口 32 连接到 IP
  3. 然后发送一个命令,等待响应并发送另一个命令。
  4. 在我们发送的 2 个命令之后,我应该得到“SNX_COM>”的响应
  5. 建立连接后,我希望连接保持打开状态,以便在单击按钮时发送特定命令。

^^这基本上就是我的代码应该实现的 ^^

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

}

日志猫

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

最佳答案

您必须将您的 createConnection(); 移动到您的异步任务的 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() 返回同类型

关于java - 使用 asynctask 进行网络连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13683676/

相关文章:

java - 使用 TestRestTemplate 进行 Spring 集成测试

android - 如何在 Flutter 的 TextField 中显示错误图标

c - 使用 select 读取和写入同一个套接字(TCP)

c - C 中的 AF_PACKET 套接字不使用 SOCK_RAW 发送空 UDP 数据包

java - 执行 .next() 方法时关闭扫描仪对象? java

java - 屏幕锁定时的android webview loadurl

java - 在EndOfMedia 上更改场景

java - 谷歌眼镜语音识别

android - 如何获取在 ContextMenu 上单击的 Item 的位置?

java - 在Java中通过TCP传输文件时,即使我指定的字节大小大于图像,它也不会传输整个图像