Чтение данных из Socket без задержки

316
14 февраля 2017, 18:10

Имеется приложение, логика которого следующая: 1) Приложение подключается к серверу. 2) При нажатии на кнопку приложение читает данные от сервера. Проблема в том, что приложение при нажатии на кнопку чтения данных приостанавливается на неопределенное время. К примеру сервер отвечает строкой: {whats,need} Приложение читает ответ, но выполнение продолжается только тогда, когда приходит следующее сообщение, либо происходит отключение. Код чтения:

public String read() throws Exception{
        String message = "";
        if (inputStream.available()>0) {
            byte[] buffer = new byte[BUFFER_SIZE];
            inputStream.read(buffer,0,inputStream.available());
            message = new String(buffer);
        }
        return message;
    }

Инициализация inputStream:

InputStream inputStream;
inputStream = clientSocket.getInputStream();

Как избавиться от этой болячки?

Answer 1

Объясняю: запускать что-то тяжелое в главном потоке приложения (он же UI поток) — нельзя. В тяжелые задачи можно отнести: чтение из БД, чтение из сервера, любая работа с файлами и длительные расчеты.

Для выполнения кода в других потоках есть такие варианты решения проблемы:

  1. AsyncTask — уже устаревшая (в плане подхода разработки) вещь, но, если не хотите заморачивать голову устойчивостью приложения, решая специфическую задачу для себя, может подойти.
  2. Intent Service — обычный Service, но предназначенный для выполнения тяжелых задач в фоне. Вполне неплохая вещь, если Вы не хотите получать результат обратно в приложение (как, например, при чтении из БД — нужно получить результат в виде массива для отображения в приложении), а просто выполнить задачу и забыть (скачай файл в телефон и просто сказать пользователю "Готово!").
  3. Loader — одна из основных вещей для выполнения длительных задач с удобным механизмом получения ответа в вызывавшую часть приложения. Устойчива к пересозданиям Activity и, что тоже интересно, не захватывает контекст, хоть и использует его.
  4. RxJava со своими методами subscribeOn и observeOn — вызывается просто, в связке с лямбдами от Retrolambda выглядит красиво. Всего в пару строк указываете в каком потоке и что выполнять. Но, опять же, нужно быть осторожно, чтобы не захватить контекст лямбдой (из-за особенностей работы Retrolambda).
  5. Thread — старый добрый "тред". Не устойчив к перезапускам активностей, имеет другие проблемы во время написания, но, как и AsyncTask, если нужно написать быстро и для себя (исключительно для себя) — подходит (в реальном приложении использовать строго запрещаю, но для себя и для имитации работы — незаменимая вещь).

Если правильно и надежно — нужно использовать Loader или RxJava. Если быстро, но ненадёжно и из палок с т.п. вещами — Thread + запрет смены ориентации устройства.

READ ALSO
Стили для подменю

Стили для подменю

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

245
Как сделать на весь экран? [требует правки]

Как сделать на весь экран? [требует правки]

Отступы не стоят,не могу понять чего так(

283
SEO страниц товаров

SEO страниц товаров

Доброго времени сутокВ интернете множество сайтов, на которых что-то продаётся

250