Как правильно использовать HandlerThread с сокетом?

Я просматривал класс HandlerThread, так как изначально использовал простой поток и обработчик, но получил ошибку NetworkOnMainThreadException в android.

Кажется, я не понимаю, как я мог бы ввести такие вещи, как сокеты, в HandlerThread, что-то, где вы запускаете блокирующий код. Но вы не можете сделать это с помощью HandlerThread, поскольку вы не должны переопределять run, поскольку именно здесь находится цикл.

И я не могу вызвать HandlerThread через сообщения, чтобы начать прослушивание сокетов, поскольку затем он заблокирует любые другие переданные ему сообщения.

Итак, этот класс HandlerThread предназначен для неблокирующих задач? Поскольку я не могу понять, как я могу использовать такой поток, чтобы он мог прослушивать сокет, но мог обрабатывать запросы Например, когда я создавал обычный поток из основного потока пользовательского интерфейса

Я мог бы в обычном потоке вызвать Looper.prepare() и Looper.loop() при запуске, а затем поместить код между этими двумя строками (с проверкой для создания обработчика), но тогда у меня возникли проблемы с общением с этот новый поток, сообщения не передаются в поток.

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

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


person NiffyDroid    schedule 19.02.2013    source источник
comment
Я провел еще несколько тестов в отдельном проекте с andengine. В OnCreate я создаю обработчик основного класса, используя onRunUIThread, затем снова создаю поток, используя onRunUIThread. Затем, если этот поток создает другой поток, новый внутренний поток должен вызвать цикл. Кажется, он работает нормально, поэтому непонятно, почему я получаю исключение NetworkOnMainThreadException, поскольку новый проект имеет те же цели и на том же телефоне, что немного сбивает с толку.   -  person NiffyDroid    schedule 21.02.2013


Ответы (1)


Думайте о HandlerThread как о рабочем потоке, у которого есть Looper, ожидающий выполнения сообщений (что может порождать новый Thread). Поэтому, чтобы общаться с ним, просто подготовьте объект Message и отправьте его обработчику (например, вы можете запустить новый thread для чтения сокета), например.

Handler handler = new Handler(handlerThread.getLooper()){
   @Override
   public void handleMessage(Message msg) {
      // Do action based on this message
   }
}

Обычно HandlerThread удобен, когда вы слушаете events, для которых требуется Looper, например. requestLocationUpdates.

Вам не нужно использовать HandlerThread, чтобы избежать NetworkOnMainThreadException (я не знаю, как вы получаете это исключение, если вы используете Thread в соответствии с вашим вопросом) и использовать его с sockets, просто используйте обычный поток и выполните операцию socket в run метод

person iTech    schedule 19.02.2013
comment
NetworkOnMainThreadException возникает из-за того, что для того, чтобы обычный поток зациклился, его необходимо обновить, иначе говоря, петлитель, поэтому создание и запуск в потоке пользовательского интерфейса настраивает петлитель для вас. но после соты вы не можете этого сделать, поэтому вы делаете петлитель самостоятельно или используете поток обработчика. Обычный поток, в который я не могу отправлять сообщения, несмотря на наличие его обработчика, handlerthread, вы не можете запустить код и не можете поместить код в метод, поскольку он заблокирует сообщения об остановке потока. Таким образом, передача сообщения для прослушивания в сокет будет заблокирована, поэтому передача сообщения для отправки в сокет будет заблокирована. - person NiffyDroid; 20.02.2013
comment
Прослушивание socket не требует Looper, поэтому вы должны делать это в обычном thread. On the other hand, sending a message on Socket can be done via HandlerThread`, потому что он не блокируется как операция чтения. Я не уверен, что именно вы пытаетесь сделать, но я не понимаю, почему вам нужен Looper для чтения из socket - person iTech; 20.02.2013
comment
Извините, в обычном Android Activity все нормально. Тем не менее, я использую andengine, так что его поток opengl, вот что вызывает проблему. - person NiffyDroid; 20.02.2013