如何从 android 中的 ansys 任务 "doInBackground" 获取列表数组?

How to get List array from ansys task "doInBackground" in android?

我正在设置 TCP 多方通信,并希望从每个服务器获取所有响应的消息。实际方法是什么?

我尝试发送 ip 数组 4 项。在日志猫上显示 "Add new item" 4 次但在 onPostExecute 显示 "Finish :: " 有时 4 次或 3 次与 "Add new item".

的数量不匹配

MultiReadingWiFiModule.class

public class MultiReadingWiFiModule extends AsyncTask<String, Integer, List<AirItem>>{
private List<AirItem> items;
private String[] ipList;
private OnReadingResult result;
private static final int CONNECT_TIMEOUT = 1000;
private static final int RESPONSE_TIMEOUT = 1000;
private static final int DATA_SIZE = 7;
private static final String TAG = "Reading";

public MultiReadingWiFiModule(String[]ipList){
    this.ipList = ipList;
}

public void startReading(){
    this.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
}

public void setOnReadingResult(OnReadingResult result){
    this.result = result;
}

@Override
protected void onPreExecute() {
    super.onPreExecute();
    Log.w(TAG, "Start reading IP list :: "+ Arrays.toString(ipList));
    items = new ArrayList<>(); //Initial air items
}

@Override
protected List<AirItem> doInBackground(String... strings) {
    // Start Threads which read WiFi module from ip list
    Thread[] scanThreads = new Thread[ipList.length];
    for (int i=0; i<scanThreads.length; i++){
        scanThreads[i] = startIPScanThread(ipList[i]);
    }
    // Wait for threads to finish
    Log.w(TAG, "Waiting for Threads...");
    int count = 0;
    for (Thread t : scanThreads){
        try {
            if (t != null){
                t.join();
            }
        }catch (InterruptedException e){
            e.printStackTrace();
        }
        count++; //Count ip test finish
        publishProgress(count*100/ipList.length); //Update progress
    }

    // Short pause seems to be necessary for ARP cache to update
    // More: https://en.wikipedia.org/wiki/ARP_cache
    Log.w(TAG, "Threads finished. "+count);
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    return items;
}

@Override
protected void onPostExecute(List<AirItem> items) {
    super.onPostExecute(items);

    for (AirItem i : items){
        Log.w(TAG, "Finish :: "+i.getIp());
    }

    if (result!=null){
        result.onFinish(items);
    }

}

private Thread startIPScanThread(final String host){
    final Thread t = new Thread(new Runnable() {
        @Override
        public void run() {
            //Declare result object
            Log.w(TAG, "Try connect "+host);
            try {
                Socket socket = new Socket();
                socket.connect(new InetSocketAddress(host, Constant.PORT), CONNECT_TIMEOUT);
                // Create PrintWriter object for sending messages to server.
                PrintWriter outWrite = new PrintWriter(new BufferedWriter(
                        new OutputStreamWriter(socket.getOutputStream())), true);
                //Send message
                outWrite.print(Constant.SCAN_INFO+","); //Request status
                outWrite.flush();
                Log.w(TAG, "Send request success!");
                //Create object for receiving message response from server.
                InputStreamReader inputStream = new InputStreamReader(socket.getInputStream());
                //Read response message
                StringBuilder s = new StringBuilder("");
                int i=0; String[]buffer = new String[Constant.BUFF_MAX];
                long start = System.currentTimeMillis(); boolean timeout = false;
                while (!timeout){
                    timeout = !((System.currentTimeMillis() - start)<RESPONSE_TIMEOUT);
                    //Convert int to char
                    char data = (char)inputStream.read();
                    //Check syntax ',' mean ending each word. So Server must send Ex: Hello,You
                    if (data==','){
                        buffer[i] = s.toString(); ///Add message to String array
                        s = new StringBuilder(""); ///Clear string
                        i++;
                    }else {
                        s.append(data); //Create word string
                    }
                    //Check InputSteam read finish
                    if (!inputStream.ready()) {
                        buffer = i > 0 ? Arrays.copyOf(buffer, i) : new String[]{s.toString()}; //Re-size buffer
                        Log.w(TAG, "Server response :: " + Arrays.toString(buffer));

                        if (buffer.length >= DATA_SIZE) {
                            Log.w(TAG, "Add new item");
                            //Show only read success
                            items.add(new AirItem(host, buffer[0], buffer[1], buffer[2], buffer[4], buffer[5], buffer[6], buffer[9]));
                        }
                        break; //Out of loop
                    }
                }

                socket.close(); //Disconnect server
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    });
    t.start();
    return t;
}


interface OnReadingResult{
    void onFinish(List<AirItem> itemsSuccess);
}
}

登录猫

   12-25 18:49:21.619 18842-18842/com.apyeng.tasakicentral W/Reading: Start 
   reading IP list :: [192.168.1.204, 192.168.1.202, 192.168.1.205, 192.168.1.203]
   12-25 18:49:21.630 18842-21156/com.apyeng.tasakicentral W/Reading: Waiting for Threads...
   12-25 18:49:21.957 18842-21159/com.apyeng.tasakicentral W/Reading: Add new item :: 192.168.1.205
   12-25 18:49:21.959 18842-21157/com.apyeng.tasakicentral W/Reading: Add new item :: 192.168.1.204
   12-25 18:49:21.960 18842-21158/com.apyeng.tasakicentral W/Reading: Add new item :: 192.168.1.202
   12-25 18:49:21.962 18842-21160/com.apyeng.tasakicentral W/Reading: Add new item :: 192.168.1.203
   12-25 18:49:21.963 18842-21156/com.apyeng.tasakicentral W/Reading: Threads finished. 4
   12-25 18:49:22.966 18842-18842/com.apyeng.tasakicentral W/Reading: 
   Finish :: 192.168.1.205
   Finish :: 192.168.1.204
   Finish :: 192.168.1.202
   Finish :: 192.168.1.203
   12-25 18:49:31.278 18842-18842/com.apyeng.tasakicentral W/Reading: Start reading IP list :: [192.168.1.203, 192.168.1.205, 192.168.1.202, 192.168.1.204]
   12-25 18:49:31.291 18842-21448/com.apyeng.tasakicentral W/Reading: Waiting for Threads...
   12-25 18:49:31.598 18842-21449/com.apyeng.tasakicentral W/Reading: Add new item :: 192.168.1.203
   12-25 18:49:31.598 18842-21452/com.apyeng.tasakicentral W/Reading: Add new item :: 192.168.1.204
   12-25 18:49:31.600 18842-21450/com.apyeng.tasakicentral W/Reading: Add new item :: 192.168.1.205
   12-25 18:49:31.606 18842-21451/com.apyeng.tasakicentral W/Reading: Add new item :: 192.168.1.202
   12-25 18:49:31.607 18842-21448/com.apyeng.tasakicentral W/Reading: Threads finished. 4
   12-25 18:49:32.609 18842-18842/com.apyeng.tasakicentral W/Reading: Finish :: 192.168.1.203
   Finish :: 192.168.1.205
   Finish :: 192.168.1.202

完成此任务的一种方法是将 ArrayList 替换为向量作为线程安全的向量。

试试下面的代码,我创建了一个同步函数来将项目添加到列表中(如果不使用向量,这是另一种选择)

public class MultiReadingWiFiModule extends AsyncTask<String, Integer, List<AirItem>>{
private List<AirItem> items;
private String[] ipList;
private OnReadingResult result;
private static final int CONNECT_TIMEOUT = 1000;
private static final int RESPONSE_TIMEOUT = 1000;
private static final int DATA_SIZE = 7;
private static final String TAG = "Reading";

public MultiReadingWiFiModule(String[]ipList){
    this.ipList = ipList;
}

public void startReading(){
     this.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
}

public void setOnReadingResult(OnReadingResult result){
     this.result = result;
 }

@Override
protected void onPreExecute() {
    super.onPreExecute();
    Log.w(TAG, "Start reading IP list :: "+ 
    Arrays.toString(ipList));
     items = new ArrayList<>(); //Initial air items
}

@Override
 protected List<AirItem> doInBackground(String... strings) {
     // Start Threads which read WiFi module from ip list
    Thread[] scanThreads = new Thread[ipList.length];
    for (int i=0; i<scanThreads.length; i++){
    scanThreads[i] = startIPScanThread(ipList[i]);
}
// Wait for threads to finish
Log.w(TAG, "Waiting for Threads...");
int count = 0;
for (Thread t : scanThreads){
    try {
        if (t != null){
            t.join();
        }
    }catch (InterruptedException e){
        e.printStackTrace();
    }
    count++; //Count ip test finish
    publishProgress(count*100/ipList.length); //Update progress
   }

// Short pause seems to be necessary for ARP cache to update
// More: https://en.wikipedia.org/wiki/ARP_cache
 Log.w(TAG, "Threads finished. "+count);
 try {
      Thread.sleep(1000);
     } catch (InterruptedException e) {
        e.printStackTrace();
    }
    return items;
}

@Override
protected void onPostExecute(List<AirItem> items) {
   super.onPostExecute(items);

   for (AirItem i : items){
       Log.w(TAG, "Finish :: "+i.getIp());
   }

  if (result!=null){
      result.onFinish(items);
  }

}

private Thread startIPScanThread(final String host){
    final Thread t = new Thread(new Runnable() {
    @Override
    public void run() {
        //Declare result object
        Log.w(TAG, "Try connect "+host);
        try {
            Socket socket = new Socket();
            socket.connect(new InetSocketAddress(host, Constant.PORT), CONNECT_TIMEOUT);
            // Create PrintWriter object for sending messages to server.
            PrintWriter outWrite = new PrintWriter(new BufferedWriter(
                    new OutputStreamWriter(socket.getOutputStream())), true);
            //Send message
            outWrite.print(Constant.SCAN_INFO+","); //Request status
            outWrite.flush();
            Log.w(TAG, "Send request success!");
            //Create object for receiving message response from server.
            InputStreamReader inputStream = new InputStreamReader(socket.getInputStream());
            //Read response message
            StringBuilder s = new StringBuilder("");
            int i=0; String[]buffer = new String[Constant.BUFF_MAX];
            long start = System.currentTimeMillis(); boolean timeout = false;
            while (!timeout){
                timeout = !((System.currentTimeMillis() - start)<RESPONSE_TIMEOUT);
                //Convert int to char
                char data = (char)inputStream.read();
                //Check syntax ',' mean ending each word. So Server must send Ex: Hello,You
                if (data==','){
                    buffer[i] = s.toString(); ///Add message to String array
                    s = new StringBuilder(""); ///Clear string
                    i++;
                }else {
                    s.append(data); //Create word string
                }
                //Check InputSteam read finish
                if (!inputStream.ready()) {
                    buffer = i > 0 ? Arrays.copyOf(buffer, i) : new String[]{s.toString()}; //Re-size buffer
                    Log.w(TAG, "Server response :: " + Arrays.toString(buffer));

                    if (buffer.length >= DATA_SIZE) {
                        Log.w(TAG, "Add new item");
                        //Show only read success
                       AirItemAdd(host, buffer[0], buffer[1], buffer[2], buffer[4], buffer[5], buffer[6], buffer[9]));
                    }
                    break; //Out of loop
                }
            }

            socket.close(); //Disconnect server
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
});
t.start();
return t;
}


interface OnReadingResult{
    void onFinish(List<AirItem> itemsSuccess);
   }


  public synchronized void AirItemAdd(String... buffer){ 


         items.add(new AirItem(buffer[0], buffer[1], buffer[2], buffer[4], buffer[5], buffer[6], buffer[9],buffer[10] ));
 }

 }