- Какую библиотеку работы с HTTP в Android выбрать?
- Для чего это вообще?
- Немного истории
- OkHttp¶
- Get a URL¶
- Post to a Server¶
- Requirements¶
- Releases¶
- MockWebServer¶
- GraalVM Native Image¶
- Android java https client
- Ktor как HTTP клиент для Android
- Простое использование
- Получаем сырой ответ
- А закрывать как-то нужно?
- Примеры помимо GET
- Отправляем form данные
- А как быть с multipart/form-data?
- Десериализуем ответ в класс
- А что еще можно
Какую библиотеку работы с HTTP в Android выбрать?
Представляю вашему вниманию перевод статьи «Which Android HTTP library to use?».
Для чего это вообще?
Немного истории
До Froyo HttpURLConnection имел некоторые не очень приятные баги. В частности, вызов close() у читаемого InputStream мог испортить пул соединений.
… большой размер их API мешает нам улучшать эту библиотеку без потери обратной совместимости. Команда Android не работает активно над Apache HTTP Client.
Apache HTTP client имеет мало багов на Eclair и Froyo, поэтому он является лучшим выбором для этих версий. А для Gingerbread и младше лучше подходит HttpURLConnection. Простота API и небольшой вес хорошо подходят для Android. Прозрачное сжатие и кэширование ответов помогают увеличить скорость и сохранить батарею. Новые приложения должны использовать HttpURLConnection.
Даже сегодня, если вы загляните в исходники Volley от Google (о ней я расскажу чуть попозже), вы сможете найти такое наследие:
Это классический пример фрагментации Android, которая заставляет страдать разработчиков. В 2013 году Square обратила внимание на эту проблему, когда выпускала OkHttp. OkHttp была создана для прямой работы с верхним уровнем сокетов Java, при этом не используя какие-либо дополнительные зависимости. Она поставляется в виде JAR-файла, так что разработчики могут использовать ее на любых устройствах с JVM (куда мы включаем, конечно, и Android). Для упрощения перехода на их библиотеку, Square имплементировали OkHttp используя интерфейсы HttpUrlConnection и Apache client.
OkHttp получила большое распространение и поддержку сообществом, и, в конце-концов, Google решили использовать версию 1.5 в Android 4.4 (KitKat). В июле 2015 Google официально признала AndroidHttpClient, основанный на Apache, устаревшим, вместе с выходом Android 5.1 (Lolipop).
Сегодня OkHttp поставляется со следующим огромным набором функций:
- Поддержка HTTP/2 и SPDY позволяет всем запросам, идущим к одному хосту, делиться сокетом
- Объединение запросов уменьшает время ожидания (если SPDY не доступен)
- Прозрачный GZIP позволяет уменьшить вес загружаемой информации
- Кэширование ответов позволяет избежать работу с сетью при повторных запросах.
- Поддержка как и синхронизированных блокирующих вызовов, так и асинхронных вызовов с обратным вызовом (callback)
Моя самая любимая часть OkHttp – как красиво и аккуратно можно работать с асинхронными запросами:
Это очень удобно, так как работа с сетью не должна быть в UI потоке. По-факту, начиная с Android 3.0 (Honeycomb, API 11), работа с сетью в отдельном потоке стала обязательной. Для того, чтобы воплотить что-то похожее с HtttpUrlConnection, вам потребуется построить большую (а может и монструозную) конструкцию с использованием AsyncTask или отдельного потока. Это будет еще более сложным, если вы захотите добавить отмену загрузки, объединение соединений и т.п.
Кстати, не осталась у обочины и HTTP библиотека от Google под названием Volley, которая предоставляет нам следующие бонусы:
- Автоматическое планирование сетевых запросов
- Множество параллельных сетевых соединений
- Прозрачное кэширование в памяти и на диске, в соответствии со стандартной кэш-согласованностью.
- Поддержка приоритизации запросов.
- Отмена API запросов. Вы можете отменить как один запрос, так и целый блок.
- Простота настройки, например, для повторов и отсрочек.
- Строгая очередность, которая делает легким корректное заполнение данными, полученными асинхронно из сети, интерфейса пользователя.
- Инструменты отладки и трассировки
Все, что ни есть в Volley, находится на вершине HttpUrlConnection. Если вы хотите получить JSON или изображение, то Volley имеет на это специальный абстракции, такие как ImageRequest и JsonObjectRequest, которые помогают вам в автоматическом режиме конвертировать полезную нагрузку HTTP. Так же достойно внимания то, что Volley использует жестко запрограммированный размер сетевого пула:
Когда OkHttp использует поток для каждого вызова с ThreadPoolExecutor с максимальным значением Integer.MAX_VALUE:
В результате, в большинстве случаев OkHttp будет действовать быстрее за счет использования бОльшего количества потоков. Если по каким-то причинам вы захотите использовать OkHttp вместе Volley, то есть реализация HttpStack, которая использует API запросов/ответов из OkHttp заместо HttpURLConnection.
HTTP клиенты продолжили развиваться для поддержки приложений с большим количеством картинок, особенно тех, кто поддерживает бесконечную прокрутку и трансформацию изображений. В то же время, REST API стал стандартом в индустрии, и каждый разработчик имел дело с такими типовыми задачами как сериализация в/из JSON и преобразование REST-вызовов в интерфейсы Java. Не прошло много времени, как появились библиотеки, решающие эти задачи:
- Retrofit – типобезопасный HTTP Android клиент для взаимодействия с REST-интерфейсами
- Picasso – мощная библиотека для загрузки и кэширования изображений под Android
Retrofit предоставляет некий мост между Java кодом и REST-интерфейсом. Он позволяет быстро включить в ваш проект HTTP API интерфейсы, и генерирует самодокументирующуюся реализацию.
В дополнение ко всему, Retrofit поддерживает конвертацию в JSON, XML, протокол буферов (protocol buffers).
Picasso, с другой стороны, предоставляет HTTP библиотеку, ориентированную на работу с изображениями. Например, вы можете загрузить изображение в свой View с помощью одной строчки:
Picasso и Retrofi настроены так, чтобы использовать OkHttpClient как стандартный HTTP клиент. Однако, если хотите, вы можете указать клиентом HttpURLConnection.
Glide – что-то похожее на Picasso. Он предоставляет некоторые дополнительные функции, такие как GIF-анимация, генерация миниатюрных эскизов изображения и неподвижные видео. Полное сравнение можно найти здесь.
Facebook недавно открыли общественности исходный код библиотеки Fresco, которую они используют в своем мобильном приложении. Одна из ключевых функций, которая выделяет ее, — кастомная стратегия выделения памяти для bitmap’ов, чтобы избежать работы долгого GC (сборщик мусора). Fresco выделяет память в регионе, который называется ashmem. Используются некие трюки, чтобы иметь доступ к этому региону памяти доступ как из части, написанной на C++, так и из части на Java. Чтобы уменьшить потребление CPU и данных из сети, эта библиотека использует 3 уровня кэша: 2 в ОЗУ, третий во внутреннем хранилище.
Я нашел необходимым показать отношения между библиотеками на одной схеме. Как вы можете увидеть, HTTP всегда остается внизу у высокоуровневых библиотек. Вы можете выбирать между простым HttpUrlConnection или последним OkHttpClient. Мы используем эту совместимость при разработке PacketZoom Android SDK, о котором мы поговорим в следующем посте.
Недавно мы сравнивали между собой HTTP библиотеки по производительности, но эта тема заслужила отдельного рассмотрения. Мы надеемся, что этот обзор дал вам основные идеи о плюсах и минусах каждой библиотеки, и мы помогли вам сделать правильный выбор. Следите за выходом более интересных постов о сетевой работе в Android от нас.
Источник
OkHttp¶
HTTP is the way modern applications network. It’s how we exchange data & media. Doing HTTP efficiently makes your stuff load faster and saves bandwidth.
OkHttp is an HTTP client that’s efficient by default:
- HTTP/2 support allows all requests to the same host to share a socket.
- Connection pooling reduces request latency (if HTTP/2 isn’t available).
- Transparent GZIP shrinks download sizes.
- Response caching avoids the network completely for repeat requests.
OkHttp perseveres when the network is troublesome: it will silently recover from common connection problems. If your service has multiple IP addresses, OkHttp will attempt alternate addresses if the first connect fails. This is necessary for IPv4+IPv6 and services hosted in redundant data centers. OkHttp supports modern TLS features (TLS 1.3, ALPN, certificate pinning). It can be configured to fall back for broad connectivity.
Using OkHttp is easy. Its request/response API is designed with fluent builders and immutability. It supports both synchronous blocking calls and async calls with callbacks.
Get a URL¶
This program downloads a URL and prints its contents as a string. Full source.
Post to a Server¶
This program posts data to a service. Full source.
Further examples are on the OkHttp Recipes page.
Requirements¶
OkHttp works on Android 5.0+ (API level 21+) and Java 8+.
OkHttp depends on Okio for high-performance I/O and the Kotlin standard library. Both are small libraries with strong backward-compatibility.
We highly recommend you keep OkHttp up-to-date. As with auto-updating web browsers, staying current with HTTPS clients is an important defense against potential security problems. We track the dynamic TLS ecosystem and adjust OkHttp to improve connectivity and security.
OkHttp uses your platform’s built-in TLS implementation. On Java platforms OkHttp also supports Conscrypt, which integrates BoringSSL with Java. OkHttp will use Conscrypt if it is the first security provider:
The OkHttp 3.12.x branch supports Android 2.3+ (API level 9+) and Java 7+. These platforms lack support for TLS 1.2 and should not be used. But because upgrading is difficult, we will backport critical fixes to the 3.12.x branch through December 31, 2021.
Releases¶
Our change log has release history.
The latest release is available on Maven Central.
Snapshot builds are available. R8 and ProGuard rules are available.
Also, we have a bill of materials (BOM) available to help you keep OkHttp artifacts up to date and be sure about version compatibility.
MockWebServer¶
OkHttp includes a library for testing HTTP, HTTPS, and HTTP/2 clients.
The latest release is available on Maven Central.
GraalVM Native Image¶
Building your native images with Graal https://www.graalvm.org/ should work automatically. Please report any bugs or workarounds you find.
See the okcurl module for an example build.
Источник
Android java https client
See the project website for documentation and APIs.
HTTP is the way modern applications network. It’s how we exchange data & media. Doing HTTP efficiently makes your stuff load faster and saves bandwidth.
OkHttp is an HTTP client that’s efficient by default:
- HTTP/2 support allows all requests to the same host to share a socket.
- Connection pooling reduces request latency (if HTTP/2 isn’t available).
- Transparent GZIP shrinks download sizes.
- Response caching avoids the network completely for repeat requests.
OkHttp perseveres when the network is troublesome: it will silently recover from common connection problems. If your service has multiple IP addresses, OkHttp will attempt alternate addresses if the first connect fails. This is necessary for IPv4+IPv6 and services hosted in redundant data centers. OkHttp supports modern TLS features (TLS 1.3, ALPN, certificate pinning). It can be configured to fall back for broad connectivity.
Using OkHttp is easy. Its request/response API is designed with fluent builders and immutability. It supports both synchronous blocking calls and async calls with callbacks.
This program downloads a URL and prints its contents as a string. Full source.
Post to a Server
This program posts data to a service. Full source.
Further examples are on the OkHttp Recipes page.
OkHttp works on Android 5.0+ (API level 21+) and Java 8+.
OkHttp depends on Okio for high-performance I/O and the Kotlin standard library. Both are small libraries with strong backward-compatibility.
We highly recommend you keep OkHttp up-to-date. As with auto-updating web browsers, staying current with HTTPS clients is an important defense against potential security problems. We track the dynamic TLS ecosystem and adjust OkHttp to improve connectivity and security.
OkHttp uses your platform’s built-in TLS implementation. On Java platforms OkHttp also supports Conscrypt, which integrates BoringSSL with Java. OkHttp will use Conscrypt if it is the first security provider:
The OkHttp 3.12.x branch supports Android 2.3+ (API level 9+) and Java 7+. These platforms lack support for TLS 1.2 and should not be used. But because upgrading is difficult, we will backport critical fixes to the 3.12.x branch through December 31, 2021.
Our change log has release history.
The latest release is available on Maven Central.
Snapshot builds are available. R8 and ProGuard rules are available.
Also, we have a bill of materials (BOM) available to help you keep OkHttp artifacts up to date and be sure about version compatibility.
OkHttp includes a library for testing HTTP, HTTPS, and HTTP/2 clients.
The latest release is available on Maven Central.
GraalVM Native Image
Building your native images with Graal https://www.graalvm.org/ should work automatically. This is not currently in a final released version, so 5.0.0-alpha.2 should be used. Please report any bugs or workarounds you find.
See the okcurl module for an example build.
Источник
Ktor как HTTP клиент для Android
Retrofit2 мне, как Android разработчику, нравится, но как на счет того, чтобы попробовать к качестве HTTP клиента Ktor? На мой взгляд, для Android разработки он не хуже и не лучше, просто один из вариантов, хотя если всё немного обернуть, то может получиться очень неплохо. Я рассмотрю базовые возможности с которыми можно будет начать пользоваться Ktor как HTTP клиентом — это создание запросов разных видов, получение raw ответов и ответов в виде текста, десериализация json в классы через конвертеры, логирование.
Если в общем, то Ktor — это фреймворк, который может выступать в роли HTTP клиента. Я рассмотрю его со стороны разработки под Android. Вряд ли вы увидите ниже очень сложные кейсы использования, но базовые возможности точно. Код из примеров ниже можно посмотреть на GitHub.
Ktor использует корутины из Kotlin 1.3, список доступных артефактов можно найти здесь, текущая версия — 1.0.1 .
Для запросов я буду использовать HttpBin.
Простое использование
Для начала работы понадобятся базовые зависимости для Android клиента:
Не забываем в Manifest добавить информацию о том, что вы используете интернет.
Попробуем получить ответ сервера в виде строки, что может быть проще?
Создать клиент можно без параметров, просто создаем экземпляр HttpClient() . В этом случае Ktor сам выберет нужный движок и использует его с настройками по-умолчанию (движок у нас подключен один — Android, но существуют и другие, например, OkHttp).
Почему корутины? Потому что get() — это suspend функция.
Что можно сделать дальше? У вас уже есть данные с сервера в виде строки, достаточно их распарсить и получить классы, с которыми уже можно работать. Вроде бы просто и быстро при таком случае использования.
Получаем сырой ответ
Иногда бывает нужно и набор байт получить вместо строки. Заодно поэкспериментируем с асинхронностью.
В местах вызова методов HttpClient , таких как call() и get() , под капотом будет вызываться await() . Значит в данном случае вызовы simpleCase() и bytesCase() всегда будут последовательны. Нужно параллельно — просто оберните каждый вызов в отдельную корутину. В этом примере появились новые методы. Вызов call(GET_UUID) вернет нам объект, из которого мы можем получить информацию о запросе, его конфигурации, ответе и о клиенте. Объект содержит в себе много полезной информации — от кода ответа и версии протокола до канала с теми самыми байтами.
А закрывать как-то нужно?
Разработчики указывают, что для корректного завершения работы HTTP движка нужно вызвать у клиента метод close() . Если же вам нужно сделать один вызов и сразу закрыть клиент, то можно использовать метод use<> , так как HttpClient реализует интерфейс Closable .
Примеры помимо GET
В моей работе второй по популярности метод — POST . Рассмотрим на его примере установку параметров, заголовков и тела запроса.
Фактически, в последнем параметре функции post() у вас есть доступ к HttpRequestBuilder , с помощью которого можно сформировать любой запрос.
Метод post() просто парсит строку, преобразует её в URL, явно задает тип метода и делает запрос.
Если выполнить код из двух последних методов, то результат будет аналогичный. Разница не велика, но пользоваться обертками удобнее. Ситуация аналогичная для put() , delete() , patch() , head() и options() , поэтому их рассматривать не будем.
Однако, если присмотреться, то можно заметить, что разница есть в типизации. При вызове call() вы получаете низкоуровневый ответ и сами должны считывать данные, но как же быть с автоматической типизацией? Ведь все мы привыкли в Retrofit2 подключить конвертер (типа Gson ) и указывать возвращаемый тип в виде конкретного класса. О конвертации в классы мы поговорим позже, а вот типизировать результат без привязки к конкретному HTTP методу поможет метод request .
Отправляем form данные
Обычно нужно передавать параметры либо в строке запроса, либо в теле. Мы в примере выше уже рассматривали как это сделать с помощью HttpRequestBuilder . Но можно проще.
Функция submitForm принимает url в виде строки, параметры для запроса и булевый флаг, который говорит о том как передавать параметры — в строке запроса или как пары в form.
А как быть с multipart/form-data?
Помимо строковых пар можно передать как параметры POST запроса числа, массивы байт и разные Input потоки. Отличия в функции и формировании параметров. Смотрим как:
Как вы могли заметить — можно ещё к каждому параметру набор заголовков прицепить.
Десериализуем ответ в класс
Нужно получить какие-то данные из запроса не в виде строки или байт, а сразу преобразованные в класс. Для начала в документации нам рекомендуют подключить фичу работы с json, но хочу оговориться, что для jvm нужна специфическая зависимость и без kotlinx-serialization всё это не взлетит. В качестве конвертера предлагаю использовать Gson (ссылки на другие поддерживаемые библиотеки есть в документации, ссылки на документацию будут в конце статьи).
build.gradle уровня проекта:
build.gradle уровня приложения:
А теперь выполним запрос. Из нового будет только подключение фичи работы с Json при создании клиента. Использовать буду открытый погодный API. Для полноты покажу модель данных.
А что еще можно
Например, сервер возвращает ошибку, а код у вас как в предыдущем примере. В таком случае вы получите ошибку сериализации, но можно настроить клиент так, чтобы при коде ответа BadResponseStatus . Достаточно устаносить при сборке клиента expectSuccess в true .
При отладке может оказаться полезным логирование. Достаточно добавить одну зависимость и донастроить клиент.
Указываем DEFAULT логгер и всё будет попадать в LogCat, но можно переопределить интерфейс и сделать свой логгер при желании (хотя больших возможностей я там не увидел, на входе есть только сообщение, а уровня лога нет). Также указываем уровень логов, которые нужно отражать.
- Работа с OkHttp движком
- Настройки движков
- Mock движок и тестирование
- Модуль авторизации
- Отдельные фичи типа хранения cookies между запросами и др.
- Всё что не относится к HTTP клиенту для Android (другие платформы, работа через сокеты, реализация сервера и т.п.
Источник