Про що мовчить Google і чому вам варто використовувати Apache HttpComponents в Android

Цю статтю потрібно було публікувати набагато раніше (майже на шість років), заощадивши тим самим Android розробникам величезна кількість місяців безглуздою розробки — але на жаль, не завжди є на це час.

Введення
Якщо ви розробляєте під Android, то напевно стикалися з тим, що ви відкриваєте свій додаток, яке відмінно працювало кілька років, і тут раптом виявляється, що Apache httpComponents стали deprecated, і їх не рекомендується використовувати. Спочатку давайте розберемо, що ж сталося, а потім зробимо висновки, що робити.

Що сталося
Занадто далеко закопуватися я не став, проте багато цікавих речей можна отримати з розсилки org.apache.hc.dev і джиры Apache. Наприклад, факт що

Android включав в себе старий pre-beta реліз бібліотеки
Більш того, протягом всієї історії версія бібліотеки не змінювалася, і якщо включаєте у себе apache legacy, то це все та ж pre-beta.
Підтвердження можна прочитати тут.
Підтвердження англійськоюGoogle Android 1.0 was released with a pre-BETA snapshot of Apache HttpClient. To coincide with the first Android release Apache HttpClient 4.0 APIs had to be frozen prematurely, while many of interfaces and internal structures were still not fully worked out. As Apache HttpClient 4.0 was maturing the project was expecting Google to incorporate the latest code improvements into their code tree. Unfortunately it did not happen. Version of Apache HttpClient shipped with Android has effectively become a fork. Eventually Google decided to discontinue further development of their fork while refusing to upgrade to the stock version of Apache HttpClient citing compatibility concerns as a reason for such decision. As a result those Android developers who would like to continue using Apache HttpClient APIs on Android cannot take advantage of newer features, performance improvements and bug fixes.

Google просто забив на проблему
Розробники з Apache активно працювали над бібліотекою, але призначені їм менеджери Google не відповідали місяцями, змінювалися, а зрештою сказали, що це не пріоритетна задача, користувачам вистачає старої версії, так і взагалі треба викинути цю бібліотеку. На підтвердження — трохи з згаданого листа розсилки (робота почалася в 2008 році, а в 2010 раптово з'явився новий менеджер):
Новий менеджер визнає, що завдання не приділяють уваги… Ну та гаразд.Jesse Wilson commented on HTTPCLIENT-898:
I'm bob's successor on the Android team. If you've got questions about our use of the HTTP client code, i'll do my best to answer 'em. I regret that we haven't given this code much attention lately; said that i'm happy that it hasn't really needed it.

Тоді ж пролунав перший тривожний дзвіночок:
Знаєте, що через два роки ми вирішили, що нічого не треба робити.i'm quite sorry that Android included an unreleased rev of Apache HTTP client and I suspect we'll be paying for that mistake for quite a while.

Because of the strict compatibility requirements of our platform, we will be unable to make forwards-incompatible API changes to the HTTP code. Unlike your desktop and serverside users, including the API as a part of the core platform significantly reduces our ability to make API changes.

These days we aren't spending much time on the HTTP client code. Our users seem to be mostly satisfied with the ancient version in the SDK, and have been directing their complaints elsewhere (crypto, locales, XML...).

That said, we do want to figure out a long term strategy for an HTTP client API that will work for both us and the Apache HTTP client team. We're considering a variety of options…

— Discouraging our users from using the built-in Apache HTTP client, preferring the JDK's own URLConnection classes. Whether this is feasible depends mostly on whether the new APIs in Java 6 (which we're working on) will satisfy the use cases that Apache HTTP client has covered for years.

— Replacing the Apache HTTP client API with a 3rd API in a «com.google» або «android.» package. Such an API would be likely based on parts of your own code, but with a more limited API.

— Tidying up the version of Apache HTTP that we're already stuck with. This includes deprecating APIs that shouldn't have ever been exposed as public, and possibly filling in any gaps using newer code from your project.

But none of this work is particularly urgent since we're actively fighting fires in other areas of the core libraries.

Вони не можуть виробляє зміни в коді існуючої бібліотеки через несумісність? Oh rly? А якщо винесуть це в свій окремий пакет на основі коду Apache, то раптово зможуть? Взагалі, breaking changes в Android це окрема тема, що виходить за рамки даної статті, але чого коштує тільки обмеження дозволів додатків в шістці… При цьому хлопці з Apache активно намагалися надати максимальну сумісність, і було готові зробити для цього все, що завгодно. Але на жаль.
Хлопців, у нас мало часу, ми взяли вашу розробку і забили на неї, не турбуйте нас по дрібницях.I explained on several earlier occasions that Android doesn't allow binary incompatibilities of any kind (not my rule). I understand that the HttpClient team is more tolerant of binary incompatibilities. While i'm not saying it would be impossible to make these changes in Android, I am saying that it would take a lot of convincing (and time), it would annoy other people who are time-constrained and who have higher priorities, and it could likely fail anyway.


Фінал
А далі бібліотеку просто без жодних адекватних пояснень випиляли з офіційною рекомендацією використовувати HttpUrlConnection. Ось хоча б щось, віддалено схоже на пояснення ситуації від Джессі Вілсона, який був на той час в Dalvik team (до речі, він же і був другим менеджером Google зв'язків з Apache. Запам'ятайте це ім'я).

У його статті ви можете побачити, що серед переваг він бачить:

  • Кешування (яке, якщо треба, реалізується де завгодно)
  • Малий вага бібліотеки (так, але сумнівний аргумент)
  • Компресія, яка зберігає батарейку і прискорює завантаження (так, але при бажанні ми можемо використовувати Google Compression Proxy і через Apache HttpComponents як звичайний проксі)
Вкрай сумнівні пояснення. Якщо ви зараз сидите в шапочці з фольги, то раціональним аргументом буде те, що гугл таким чином вирішив нишком змусити користувачів ганяти весь свій трафік через свій проксі…
На жаль, більшість розробників сліпо вірять Google і одразу вважають, що бібліотека Apache «погана», і потрібно бігти викидати її з свого коду.
Розробники з Apache прокоментували це коротко:
Google has used the project when it suited their goals and screwed us afterwards. There is nothing we can do about it.


Епілог c OkHttp
Якщо ви розробляєте під Android, то напевно бачили рекомендації замінювати Apache HttpComponents нині популярної бібліотекою OkHttp від Square.
А ви все ще пам'ятаєте милого хлопця Джессі Вілсона з Dalvik team? А ви знаєте, що зараз він працює в Square? І саме він є творцем OkHttp? Більш того, ви знате, що OkHttp починався як форк шматка AOSP (Android Open Source Project), який у свою чергу брав свій код з Apache Harmony?
Так що це і є по суті створення форк Apache з подальшим выкидыванием оригіналу з обігу (другий варіант з озвучених раніше Джессі у спілкуванні з Apache). Звучить досить огидно, чи не правда? Єдине, що незрозуміло — чи це була ініціатива Google або самого Джессі. Але вступив він вкрай некрасиво, викинувши конкурентів з Google і прийшовши весь у білому зі своїм рішенням.

І що ж?
Давайте розберемося, які є варіанти того, як жити далі.

1. Використовувати HttpUrlConnection
Рекомендований підхід Google. Дійсно має сенс, якщо у вас просте додаток. Але не дай бог вам спробувати зробити що-то не зовсім тривіальне. У моїй практиці було два таких випадки — коли я намагався використовувати SSL проксі і коли хотів звернутися до якогось айпишнику зі своїм ім'ям хоста. Обидві задачі за допомогою HttpUrlConnection реалізувати неможливо.

2. Використовувати інші просунуті альтернативи
Наприклад, той же OkHttp. Сам не пробував, але кажуть, що хороша бібліотека. Однак, ви витратите багато часу на переписування хорошого готового коду (якщо у вас уже є додаток). Ну і стосовно саме OkHttp — я б не став використовувати настільки неприємно пахне форк.

3. Використовувати legacy бібліотеку
Так, ви можете продовжувати використовувати всю ту ж древню бету, що і раніше. Але навіщо? Як швидке затикання дірок це непогане рішення, а якщо ні… То звичайно немає. Прикро, що саме така відповідь є найбільш популярним рішенням на тому ж stack overflow — люди просто не розуміють, що вони використовують версію бібліотеки від 2008 року.

4. Використовувати останні версії Apache HttpComponents
В плюсах маємо те, що ми продовжуємо використовувати той же код, не витрачаючи час на переписування і на вивчення нової бібліотеки та її багів. Більш того, код написаний на HttpComponents буде у вас працювати де завгодно. Бібліотека напрочуд потужна і дозволяє вам зробити дійсно що завгодно.
Питання — як її підключати?
Якщо просто брати і підставляти в gradle, то вийде конфлікт класів з цієї самої древньої версією.
У релізі 4.3 розробники apache пропонували використовувати спеціальні постфиксы «HC4» в класах для уникнення конфліктів, але працювало це якось дуже погано.
Зате до релізу 4.5 вони вже рекомендують інший, єдино логічний вихід — використовувати перепакованную під іншим простором класів бібліотеку, зібрану якимсь товаришем на гітхабі (посилання нижче). Там, правда, насправді версія 4.4, а не 4.5 — але це не так принципово. А якщо вас хвилює, що ви використовуєте зібрану незрозуміло ким бібліотеку (хоча вона досить популярна), то ви завжди можете зібрати її самі з исходников. На даний момент я вважаю це найбільш правильним виходом із ситуації дурної ситуації (і сам роблю саме так).

Що далі?
Заміток по використанню п'ятої версії бібліотеки на Android поки що немає — можливо, це пояснюється тим, що вона поки ще в альфа-версії. Або просто в Apache вирішили більше не мати справи з Google Android. Втім, навіть якщо так — завжди знайдуться ентузіасти, які зможуть коректно перепакувати останню версію. А працювати з нею — одне задоволення.

Посилання
  1. Репозиторій з перепакованной версією httpComponents;
  2. Примітки про релізі 4.5, де рекомендують використовувати цей репозиторій;
  3. Цікаві фрагменти листування хлопців з Apache і Google;
  4. Цікаві завдання з коментарями в джире Apache — раз і два.
У процесі написання статті я спілкувався на цю тему з розробником з Apache, який підтвердив мої припущення, але від гріха подалі згадувати його тут не буду.
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.