2011-10-14 2 views
0

У меня есть приложение для Android с большим количеством кнопок. Если кнопка нажата, он отправляет короткий cmd на сервер через сокет.андроид приложение отправки небольших cmds через сокет

В настоящее время, когда нажата кнопка, это добавляет cmd в список. У меня есть рабочий поток, который постоянно проверяет список для cmds, и если он обнаруживает, что он открывает сокет и отправляет cmd.

Это не очень эффективно, так как рабочий поток постоянно работает. Какой был бы лучший способ улучшить это?

public class Arduino implements Runnable{ 

private static PrintWriter arduinoOutput; 
private static Socket ss; 
private static Queue<String> cmdsToSend=new LinkedList<String>(); 
private static String cmd; 

public void run(){ 
    while(true){ 
     if(!cmdsToSend.isEmpty()){ 
      cmd = cmdsToSend.poll(); 
      System.out.println("send:"+cmd); 
      if(connect()){ 
       arduinoOutput.println(cmd); 
       disconnect(); 
      } 
     } 
    } 
} 

public static void sendCmd(String newcmd){ 
    cmdsToSend.add(newcmd); 
} 

private static boolean connect(){ 
    try { 
     ss = new Socket(); 
     InetAddress addr = InetAddress.getByName("192.168.1.8"); 
     int port = 23; 
     SocketAddress sockaddr = new InetSocketAddress(addr, port); 
     ss.connect(sockaddr, 2000); 
     arduinoOutput = new PrintWriter(ss.getOutputStream(),true); //Autoflush 
     return true; 
    } catch (UnknownHostException e) { 
     return false; 
    } catch (IOException e) { 
     return false; 
    } 
} 

private static void disconnect(){ 
    arduinoOutput.close(); 
    try { 
     ss.close(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
} 

}

Пользовательский интерфейс активности добавляет ЦМД, вызывая Arduino.sendCmd ("cmdName"); Cmds нужно отправить как можно быстрее, чтобы спать в петле не было хорошо. Любые идеи или примеры будут оценены.

ответ

0

Используйте шаблон ожидания/уведомления. Поместите отправителя в поток со списком. Всякий раз, когда есть что писать в рабочий поток, попросите автора добавить команду, а затем уведомить поток. Если поток уже проснулся, уведомление ничего не сделает.

Вот краткий пример, очевидно, что механизм, который вы будете использовать для начала записи, будет отличаться.

import java.util.LinkedList; 
import java.util.Queue; 
import java.util.concurrent.ThreadFactory; 

public class Notifier 
{ 
    public static void main(String args[]) 
    { 
     Writer writingThread = new Writer(); 
     writingThread.addToQueue("Command 0"); 
     ThreadFactory.submitInSingleThread(writingThread); 

     for (int i = 1; i < 1000; i++) 
     { 
      writingThread.addToQueue("Command " + i); 
      writingThread.notify(); 
     } 
    } 

    static class Writer implements Runnable 
    { 
     private static Queue<String> cmdsToSend = new LinkedList<String>(); 

     public void addToQueue(String cmd) 
     { 
      cmdsToSend.add(cmd); 
     } 

     @Override 
     public void run() 
     { 
      while(true) 
      { 
       if(!cmdsToSend.isEmpty()) 
       { 
        String cmd = cmdsToSend.poll(); 
        System.out.println("send:" + cmd); 
        if(connect()) 
        { 
         arduinoOutput.println(cmd); 
         disconnect(); 
        } 
       } 

       synchronized(this) 
       { 
        wait(); //Can add a timer (100ms, for example) 
       } 
      } 
     } 
    } 
} 
+0

При исследовании этого шаблона ожидания/уведомления я нашел более легкое решение, изменив очередь на BlockingQueue. Спасибо, что указал мне в правильном направлении. private static BlockingQueue cmdsToSend = new LinkedBlockingQueue (); Затем вместо использования cmdsToSend.poll() вы можете использовать cmdsToSend.take(); – smee204

+0

Ницца! Не стесняйтесь отвечать и принимать свой вопрос с полезной информацией, так как я фактически не давал вам то, что вам нужно. – Noah

Смежные вопросы