Слушатель для другого потока - PullRequest
0 голосов
/ 07 марта 2011

У меня есть приложение с графическим интерфейсом и TCP-сервером.Сервер TCP работает в другом потоке, и при получении определенного пакета он должен начать воспроизведение видеофайла (из объекта MediaPlayer).Проблема заключается в том, что в качестве компонента графического интерфейса видео может отображаться только в том случае, если оно вызывается из основного потока.Я добавил класс слушателя в основной класс:

Class RequestListener implements NBRequestListener{  /* NBRequestListener is the interface */
public void onRequestArrived(String request) {
processRequest(request); /* This method will run the video */
}

Я создал слушателя в главном потоке и установил его в качестве слушателя на сервере:

RequestListener listener = new RequestListener();
server.setRequestListener(listener);

Код всервер:

public void setRequestListener(_listener) {
listener = _listener; } /* listener is defined as RequestListener */

и вызов события (на сервере) просто:

listener.onRequestArrived(input_from_client);

Но метод слушателя вызывается в потоке сервера, а не в основномнить и, следовательно, я получаю исключение: java.lang.reflect.InvocationTargetException.Не могли бы вы помочь определить проблему?

Ответы [ 3 ]

1 голос
/ 07 марта 2011

Множество способов решить эту проблему, вот два:

  1. Используйте обработчик в своей деятельности. Например, когда вы получаете уведомление из фоновой ветки о том, что видео необходимо воспроизвести, вы отправляете сообщение обработчику вашей активности. Код в вашем собственном обработчике запускается в потоке пользовательского интерфейса. Вот учебник (из множества) http://www.helloandroid.com/taxonomy/term/43

  2. Когда фоновый поток получает пакет, передает Intent (startBroadcast () в классе контекста). Зарегистрируйте получателя для этой трансляции в своей деятельности.

0 голосов
/ 07 марта 2011

Многим пользовательским интерфейсам требуется только один поток (поток «событий») для выполнения операции над состоянием пользовательского интерфейса.Это необходимо для предотвращения проблем параллелизма и непротиворечивости.

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

В свинге это выглядит примерно так:

SwingUtilities.invokeLater(new Runnable(){
  public void run(){
    //Your UI code to be run in the context of the event thread.
    //In your case linking the video.
  }
});

Как высказал, что вы не должны блокировать поток пользовательского интерфейса, или он будет блокировать его.

0 голосов
/ 07 марта 2011

Обычный способ - заставить поток потребителя (здесь, ваш основной поток) ожидать семафор или блокировку, а поток производителя (здесь, серверный поток) освобождает семафор или блокировку, когда ресурс доступен (т.е. когда был получен ввод от клиента).

Посмотрите на Lock и Semaphore в пакетах java.util.concurrent и java.util.concurrent.locks.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...