четверг, 13 августа 2015 г.

Знайомство з Volley

Volley - це бібліотека для роботи з мережею, розроблена копанією Google та представлена протягом презентації Google I/O в 2013 році. Вона була розроблена через відстутність в Android SDK класу здатного працювати без втручання в UX.
До випуску бібліотеки Volley, єдиними доступними варіантами для розробників були Java class java.net.HttpURLConnection та Apache org.apache.http.client,так розробники могли реалізовувати роботу між клієнтом та сервером для RESTful систем.
Відклавши в бік той факт, що ці два класи не звільняють вас від винекнення багів, слід відмітити, як все, що проходить поза простими HTTP транзакціями має бути написано заново. Якщо ж вам потрібно було закешувати зображення чи оптимізувати запити, ви мали розробляти його з нуля.
На щастя, зараз бібліотке Volley, повністю задовольняє такі потреби.
На пристроях з низьким рівнем API (найчастіше на Gingerbread та Froyo), HttpUrlConnection та HttpClient далекі від ідеалу. Існує декілька відомих проблем та багів, що досі не були виправлені. Більше тог, HttpClient був позначений як deprecated в останньому оновленні API (API 22), що означає, що вона (бібліотека) більше не буде підтримуватись, а в майбутньому і взагалі буде видалена.
Це є достатньою причиною перейти на більш надійну та підтримувану бібліотеку для роботи з мережею.
З часу представлення Honeycomb (API 11), стало обов'язковим виконувати операції по роботі з мережею в окремих потоках і аж ніяк не в головному. Ця суттєва зміна привела до масового використання AsyncTask<Params, Progress, Result> специфікацій.
Використовуючи AsyncTask, ви спершу визначаєте деякі підготовчі дії, як наприклад визначення контексту в onPreExecute. Далі ви виконуєте ваші асинхронні завдання за допомогою doInBackground методу. І врешті решт, ви користуєтесь результатом в методі onPostExecute. Це достатньо простий спосіб і точно простіше ніж реалізація сервісу, в комплекты з тонами прикладів та документацією.
Основною пробелемою являється серіалізація викликів. Використовуючи клас AsyncTask, ви не можете вирішити який з запитівв піде першим, а який має трохи зачекати.
Виникають проблеми, наприклад, коли ви маєте завантажити список елементів з прикріпленими мініатюрами (thumbnail). Коли користувач прокручує вниз і очікує отримати результат, ви не можете сказати activity спочатку завантажити JSON наступної сторінки і тільки потім зображення з попередньої. Це може статити для вас серйозною проблемою UX для додатків подібних Facebook чи Twitter, де список нових елементів важливіший ніж зображення кожного окремого.
Головна мета Volley вирішити ці проблеми методом включення потужних API анулювання. Вам більше не потрібно перевіряти onPostExecute чи була activity знищена під час виконання виклику. Це допомагає уникати NullPointerException.
Недавно, команда Google+ провела серйозне тестування продуктивності по кожному окремому методу, що ви могли б використовувати для мережевих запитів в Android. Volley отримала набагато більшу оцінку аніж інші альтернативні бібліотеки при використанні в RESTful додатках.
Volley автоматично кешує запити  і це, насправді, інколи, просто, рятує життя. Та все ж повернемося на хвилинку до прикладу приведеного раніше. Ви маєте список елементів — JSON масив скажемо — і кожен елемент має іконку та опис. Тепер подумайте, що трапиться, коли користувач змінить орієнтацію екрану: актівіті знищиться, список буде завантажено заново, так само як і зображення. Кортше кажучи, значна трата ресурсів та слабкий UX.
Volley підтверджує свою надважливість при виникненні даної проблеми. Вона запам'ятовує попередній виклик та управляє знищенням та перестворенням актівіті. Вона (бібліотека Volley) кешує все не змушуючи вас хвилюватись про це.
Ще Volley ідеально підходить для коротких викликів, як наприклад, JSON об'єкти, шматки списків, деталі вибраних елементів і так далі. Це було винайдено для додатків, що працюють з RESTful і в конкретних випадках вона є незамінною.
Це не так вже й добре виглядає при запущених потокових операціях та великих завантаженнях. На противагу загальним віруванням, назва бібліотеки Volley не веде своє коріння зі спортивного словника. Вона скоріше призначена для повторюваних викликів, згрупованих разом. Це й зрозуміло само собою, коли ви замість граду стріл запускаєте гарматою м'ячі. (when, instead of a volley of arrows, you want to fire a cannon ball).
Volley працює на трьох різних рівнях з окремем рівнем операцій в його окремому потоці.



Volley under the hood

В головному потоці, ви займаєтесь запуском запитів та управлінням відповідями відповідно до специфікацій AsyncTask. Ні більше, ні менше.
Головною особливістю є те, що ви можете ігнорувати все, що коїться в методі doInBackground. Volley автоматично управляє HTTP транзакціями та відловом мережевих помилок, про які вам необхідно піклуватися.
Коли ви додаєте запит до черги, декілька речей виконуються під капотом. Перше, Volley  первіряє чи запит може бути виконаний з кешу. Якщо це так, закешована відповідь (responce) зчитується, розбирається та доставляється. В іншому випадку він переходить до потоку мережі.
В потоці мережі, проходить постійна циклічна робота з серією потоків. Перший вільний потік, що витягує запит, робить HTTP запит, аналізує відповідь та записує його в кеш. Для завершення він відправляє проаналізовану відповідь назад в головний потік де ваш listener чекає на обробку результату.
Volley, насправді, не так-то й просто налаштувати. Виглядає це так ніби офіційного репозиторію Maven у бібліотеки немає і це трохи бентежить. Ви маєте покладатися на офіційний вихідний код. Ви можете імпотрувати Volley одним з декількох способів.
Але все по черзі, завантажити вихідний код Volley можна за посиланням на репозиторій. Можна також скористатися командою Git:
Ще недавно, ви могли  зібрати все командою ant з консолі (android update project -p . і потім ant jar) та імпортувати вашу JAR бібліотеку у ваш проект в Android Studio командою compile files('libs/volley.jar').
З недавніх пір, не дивлячись на те, що Google оновили Volley в стилі білдів Android Studio, стало важче створювати незалежні файли JAR. Ви досі можете це зробити, але тільки з старшою версією бібліотеки. Особисто я, не рекомендував би вам користуватися даним способом, навіть, якщо це здається вам швидшим та простішим варіантом.
Вам потрібно налаштувати Volley класичним способом, а саме, імпортувати вихідний код як модуль. В Android Studio, у відкритому проекті, натисрніть File > New Module, та оберіть Import Existing Project. Виберіть директорію де зберігається завантажений вами вихідний код та підтвердіть вибір. Директорія з назвою Volley з'явиться в структурі вашого проекту. Android Studio автоматично оновить файл settings.gradle та включить модуль Volley вам залишається тільки додати залежність (dependency) compile project(':volley') і все.
Існує третій спосіб. Ви можете додати залежність в файл build.gradle такий рядок:
Це копія офіційного репозиторію Google, що регулярно синхронізується та оновлюється. Це імовірно найпростіший та найшвидший спосіб для швидкого старту. Тим не менше, будьте обережні, це не офіційний репозиторій Maven, ніяких гарантій та зворотнього зв'язку з Google можна не чекати.
На мою думку, краще виділити декілька хвилин на імпортування офіційного вихідного коду. Таким чином, ви можете просто пересочити до оригінальних визначень та реалізації, що, у випадку, якщо ви не впевнені, ви завжди можете покластися на офіційний вихідний код Volley  — і навіть змінити його самостійно, якзо це необхідно.
Volley в основному працює лише з двома основними класами, RequestQueue та Request. Спочатку ви створюєте RequestQueue, який управляє працюючим потоком та доставляє отримані відповіді назад в головний потік. Далі ви передаєте його в один чи декілька об'єктів типу Request.
Конструктор Request завжди приймаж параметри типу (GET, POST, і т.д.), URL ресурсу,  listener подій. Далі, в залежності від типу запиту, він може попросити ще декілька змінних.
В наступному прикладі, я створив об'єкт типу RequestQueue використовуючи метод бібліотеки Volley а саме, Volley.newRequestQueue. Він налаштовує об'єкт RequestQueue, використовуючи значення за замовчуваням визначені бібліотекою Volley.
Як бачите, це все неймовірно просто. Ви створюєте запит та додаєте його в чергу запитів. Це все.
Зауважте, що синтаксис listener подібний до AsyncTask.onPostExecute, як onResponse. Це не співпадіння. Розробники, що працювали над Volley цілеспрямовано зробили API бібліотеки подібним до методів AsyncTask. Це робить перхід з використання AsyncTask до Volley настільки простим.
Якщо ви маєте запустити безліч запитів в декількох activitу, вам слід уникати використання попереднього підходу, Volley.newRequestQueue.add. Набагато краще створити екземпляр  shared request queue та використовувати його протягом всього проекту:
Ми побачимо конкретні розробки чогось подібного в наступній статті даної серії.
Бібліотека Volley зручна в реалізації трьох дуже розповсюджеих типів запиту:
  • StringRequest
  • ImageRequest
  • JsonRequest
Кожен з цих класів розширює (extend) клас Result, який ми використовували раніше. Ми вже розглянули StringRequest в минулому прикладі. Давайте поглянемо тепер на те як працює клас JsonRequest.
Прекрасно. Чи не так? Як ви можете бачити, тип результату вже установлено в JSONObject. Ви можете запзапросити JSONArray також, якщо вам це потрібно, використовуйте JsonArrayRequest замість JsonObjectRequest.
Як ранішк, перший параметр конструкотра це HTTP метод. Далі забезпечуєте URL витягнути JSON. Третя змінна в приведеному вище прикладі null. Це нормально, так як це означає параметри не будуть відправлені з запитом. Нарешті, ви маєте listener для отримання віповіді JSON та listener для помилок. Ви можете передати null якщо ви хочете ігнорувати помилки.
Завантаження зображень потребує трохи більше роботи. Існує три можливих методи для запитів на зображення. ImageRequest - стандартний метод. Він відображає зображення на яке ви відправляєте запит в ImageView, повертаючи його через наданий URL. Все декодування та операції масштабування виконує Volley в робочому потоці. Другий спосіб це клас ImageLoader, який ви можете представити собі як організатор великої кількості запитів ImageRequests, наприклад, заповнити ListView зображеннями. Третій спосіб це NetworkImageView, який є заміною XML для ImageView шару елементів.
Поглянемо на приклад.
Перший параметр це URL зображення, а другий це listener для результату. Третій і четвертий це числові параметри, які відповідають за максимальну ширину та висоту: maxWidth і maxHeight відповідно. Ви можете встановити їх в 0 і вони будуть проігноровані. Після цього, ImageRequest буде запитано ScaleType для обчислення розмірів зображення та для формату декодованого бітмапу. Я рекомендую завжди використовувати Bitmap.Config.ARGB_8888. Нарешті, ми потрапили в error listener.
Зверніть увагу, що Volley автоматично встановлює пріорітет цього запиту на LOW.
Перейти  з запиту GET до запиту POST дуже просто. Ви маєте змінити в Request.Method в конструкотрі запиту та перевизначити (override) метод getParams, повернути відповідний Map<String, String> що містить параметри запиту, як показано в прикладі нижче:
Якщо ви хочете відмінити всі ваші запити, додайте наступний шматок коду в метод onStop:
Таким чином, ви будете хвилюватися про можливість того, що користувач вже знищив activity при виклику мотоду onResponse. В такому випадку NullPointerException може виникнути.
POST та PUT запити, тим не менше, слід продовжити, навіть після того як користувач зміним activitу. Досягнути цього ми можемо з використанням тегів(tag). Коли конструюється запит GET, додайте до нього тег.
Щоб відмінити кожен запит GET в черзі, ми просто додаємо наступний рядок коду:
Так, ви тільки відмінюєте GET запити, не зачіпаючи решту запитів. Прийміть до уваги, що тепер ви маєте вручну управляти ситуаціями в яких activity зищується достроково.
Volley не надає мотодів для налаштуванн cookies для запитів (request) та пріорітети виконання (priority). Можливо вони будуть додані в майбутньому, а до того часу це серйозна втрата. Все ж, щоб справлятися з подібними потребами ми маємо наслідуватись (extend) від класу Request.
Для управління cookies, ви можете використовувати хедери (headers) запитів, перевизначаючи (overriding) метод getHeaders:
З реалізацією, ви можете безпосередньо забезпечувати список cookies в request використовуючи setCookies.
Для налаштування пріорітетів, ви також маєте наслідуватись від класу Request, перевизначивши метод getPriority. Так виглядає реалізація:
Далі, в головному потоці, даним рядком установлюється пріорітет запиту:
Пріорітет можна вибрати з чотрирьох доступних, як показано нижче:
В даній статті, ми розглянули роботу бібліотеки Volley з мережею. Спочатку ми розібралися чому і коли саме краще використовувати Volley на відміну від інших рішень, вже включених до Android SDK. Далі ми поглибились в недра бібліотеки, розбираючись з процесом роботи та підтримуваними типами запитів. В кінці кінців, ми забруднили руки, створюючи прості запити та реалізуючи кастомну роботу для управління cookies та пріорітетами.
В наступній частині серії про Volley, ми створимо простий додаток з використання бібліотеки Voley. Я покажу вам як зробити додаток, який показує погоду, де б ви думали? На самому Марсі, з використовуючи дані забрані ровером, який зараз їздить по Марсу, а саме Curiosity.

source

Комментариев нет:

Отправить комментарий