2012-06-11 2 views
2

Я разрабатываю приложение для Android.Общайтесь с рабочей нитью с основной темой

Это приложение будет иметь сервер для запуска DatagramSocket в качестве сервера. Он будет ждать входящего сообщения. Когда сокет получит сообщение, я обработаю его.

Чтобы запустить гнездо UDP-сервера, я собираюсь использовать локальную службу. Эта служба будет иметь рабочий поток, где я буду слушать входящие сообщения.

Это моя незавершенной реализация Локальной службы:

public class UDPSocketBackgroundService extends Service 
{ 
    private static final String TAG = "UDPSocketBackgroundService"; 
    private ThreadGroup myThreads = new ThreadGroup("UDPSocketServiceWorker"); 
    private Handler mServiceHandler; 

    @Override 
    public void onCreate() 
    { 
     super.onCreate(); 
     Log.v(TAG, "in onCreate()"); 
    } 

    @Override 
    public IBinder onBind(Intent arg0) 
    { 
     try 
     { 
      new Thread(myThreads, new UDPServerThread("X", 8888)).start(); 
     } 
     catch (IOException e) 
     { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     return null; 
    } 
} 

И это моя также незавершенной рабочей реализации Темы:

public class UDPServerThread extends Thread 
{ 
    private static final int MESSAGE_SIZE = 256; 

    protected DatagramSocket socket = null; 
    protected boolean end = false; 

    public UDPServerThread(String serverName, int port) throws IOException 
    { 
     super(serverName); 
     socket = new DatagramSocket(port); 
    } 

    public void run() 
    { 
     while (!end) 
     { 
      try 
      { 
       byte[] buf = new byte[MESSAGE_SIZE]; 

       // Wait an incoming message. 
       DatagramPacket packet = new DatagramPacket(buf, buf.length); 
       socket.receive(packet); 
       // TODO: Notify Service with packet received 
      } 
      catch (IOException e) 
      { 
       // TODO Mensaje de error. 
       e.printStackTrace(); 
      } 
     } 
    } 
} 

Эти классы имеют свой собственный файл (они находятся на разные файлы).

Здесь:

socket.receive(packet); 
//TODO: Notify Service with packet received 

Как я могу уведомить службу, мы получили пакет? Я также хочу отправить этот сервис.

Here есть пример того, как связаться с основной нитью, чтобы рабочий поток. Но мне это не нужно, я ищу пример того, как общаться из рабочего потока в службу.

Я нашел это example, но я не очень хорошо его понимаю, потому что в этом примере оба класса объявляют его в том же файле.

Как вы можете видеть, я новичок в разработке Android.

Если вы знаете лучший подход, пожалуйста, скажите мне.

+0

Этот код имеет две большие проблемы: во-первых, конструктор 'Thread (ThreadGroup , Runnable) ', а в качестве второго аргумента передается' Thread'. Это ошибка, и этот поток никогда не начнется. Вместо этого следует использовать не-поток 'Runnable'. Во-вторых, нет смысла использовать 'ThreadGroup'. Citing * Эффективная Java *: "* группы потоков устарели *". – Lii

ответ

0

Когда вы создаете UDPServerThread, вы можете передать ссылку на UDPSocketBackgroundService, а затем вызвать метод на нем (например, processPacket()) при получении пакетов. Этот метод processPacket() должен использовать какую-то синхронизацию.

Вот небольшой фрагмент кода из соответствующих функций:

public class UDPSocketBackgroundService extends Service 
{ 
    .... 
    @Override 
    public IBinder onBind(Intent arg0) 
    { 
     try 
     { 
      new Thread(myThreads, new UDPServerThread(this, "X", 8888)).start(); 
      // Notice we're passing in a ref to this ^^^ 
     } 
     ... 
    } 
    public void processPacket(DatagramPacket packet) 
    { 
     // Do what you need to do here, with proper synchronization 
    } 
} 

public class UDPServerThread extends Thread 
{ 
    private static final int MESSAGE_SIZE = 256; 

    protected DatagramSocket socket = null; 
    protected boolean end = false; 
    protected UDPSocketBackgroundService = null; 

    public UDPServerThread(UDPSocketBackgroundService service, String serverName, int port) throws IOException 
    { 
     super(serverName); 
     this.service = service; 
     socket = new DatagramSocket(port); 
    } 

    ... 

    public void run() 
    { 
     while (!end) 
     { 
      try 
      { 
       byte[] buf = new byte[MESSAGE_SIZE]; 

       // Wait an incoming message. 
       DatagramPacket packet = new DatagramPacket(buf, buf.length); 
       socket.receive(packet); 
       service.processPacket(packet); 
      } 
      ... 
     } 
     ... 
    } 
} 

Обратите внимание, что происходит такой подход, UDPSocketBackgroundService теперь «тесно связан» с UDPServerThread. Как только вы это сделаете, вы можете подумать о его реорганизации с более элегантным дизайном, где есть меньше связи, но на данный момент это должно вас завести :)

+0

Спасибо за ваш ответ, но у меня есть другой вопрос: моя служба находится в другом потоке, который UDPServerThread. Является ли это законным, если я вызываю метод службы из UDPServerThread? – VansFannel

+0

@VansFannel, должно быть хорошо, но вы должны использовать синхронизацию, как указано в ответе, чтобы решение было потокобезопасным и последовательным.Общий подход был бы для потоков, которые принимают данные для размещения данных в какой-то общей очереди, очереди в службе в этом случае, что позволяет им продолжать получать данные. – Brady

+0

@VansFannel, как это сработало для вас? – Brady

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