пятница, 14 августа 2015 г.

Погода на Марсі з використанням бібліотеки Volley




Final product image
Ось, що ми отримаємо в результаті

У цій статті, я покажу вам один з можливих практичних способів використання знань, які ви здобули в попередній статті про бібліотеку Volley. Ми будемо створювати додаток для відображення погоди на Марсі, використовуючии інформацію зібрану ровером Curiosity, яка тепер доступна кожному завдяки NASA через {MAAS} API.
Спочатку, ми налаштує проект в Android Studio та спроектуємо користувацький інтерфейс. Далі ми будемо конструювати ядро додатку за допомогою Volley. Зважаючи на те, що кожен додаток, так чи інакше, оперує зображеннями, я покажу, як стягнути випадкове зображення використовуючи Flickr API. Ми будемо завантажувати зображення за допомогою Volley, в основному через її чудову систему кешування. І в кінці,  ми додамо декілька прикрашальних функцій, щоб надати нашому додатку ефектності.
Створимо новий проект в Android Studio. Бібліотека Volley зворотньо-сумісна, а отже ви можете вибрати будь-який рівень API, який вам заманеться. Я вибрав API 21, але ви можете обрати API починаючи з 8 (Froyo) чи вищих.
Наш додаток має єдину актівіті. Ви можете назвати MainActivity.java, як рекомендує Android Studio. Відкрийте редактор шару розмітки activity_main.xml.
Зважаючи на те що у нас зображення буде займати приблизно 70% екрану, а те, що залишилось буде займати інформація про погоду, ми маємо використати атрибут XML такий як layout_weight. Звичайно, ми можемо вказати абсолютні значення також, але але вони не будуть однаковими для всіх пристроїв. Нажаль, у світі Android не все так просто з розмірами. Атрибут layout_weight допоможе нам вирішити проблему.
Додамо ImageView:
В другому RelativeLayout, ми додамо список з TextView елементів. Двоє з них будуть показувати середню температуру атмосфери. Третій для повідомлень про помилку.
З UI ми справилися. Ви можете додати більше деталей, якщо маєте таке бажання, але для демонстрації роботи бібліотеки роботи з мережею і цього буде достатньо.
Є ще дві речі, про які ми мали б попіклуватися перш ніж поринути в ядро додатку. Змінимо тему додатку на android:Theme.Material.Light.NoActionBar. Це означає, що ми не будемо приховувати action bar при запуску.
Нарешті,додаму дозвіл на доступ до інтернету в маніфесті проекту.
Як ми вже обговорили в попередній статті, найпростіший спосіб та в той же час найнадійніший використовувати бібліотеку Volley це імпортувати бібліотеку як модуль. Завантажте вихідний код бібліотеки та імпортуйте його через File > New > Module, та в файі build.gradle додайте рядок.
Як вже було вказано pаніше, якщо вам потрібно запускати безліч проектів, краще використовути загальну чергу запитів (shared request queue). Вам краще уникати від створення черги запитів кожен раз, коли робите запит за допомогою Volley.newRequestQueue, через те що нікому не потрібні витоки пам'яті (memory leaks) та інші не потрібні проблеми.
Задля цього, створимо клас, який буде працювати за шаблоном проектування одинак. Клас працює з статичною, глобально видимою змінною, яка управляє об'єктом RequestQueue. Таким чином, ви покінчили з RequestQueue. Далі, наслідуємось від класу Application, ви маєте сказати операційній системі згенерувати об'єкт при старті програми, перед стартом першої актівіті.
Трихи підправимо структуру нашого одинака (singleton). Потрібно створити новий екземпляр класу в методі Application.onCreate, а не getInstance коли він рівний null.
Щоб досягти цього, створимо новий клас і назвемо його MarsWeather.java. Далі, додамо йому предка Application, перевизначимо метот onCreate, та ініціалізуємо об'єкт статичного екземпляру RequestQueue.
У цьому класі, ми конструюємо об'єкт, використовуючи модифікатори public та synchronized функцію getInstance. Всередині методу, ми повертаємо mInstance змінну. Метод onCreate виконується при старті додатку отже змінна mInstance вже стоврена методом getInstance.
В файлі AndroidManifest.xml зазначимо, що нам необхідно щоб клас MarsWeather був завантажений при старті дадатку. В тег <application> додамо атрибун name як показано нижче:
Готово. Екземпляр класу Application створений, ще до того як клас MainActivity створений. Разом зі стандартними операціями, метод onCreate згенерує екземпляр RequestQueue.
Ми маємо реалізувати інші методи задля завершення  допоміжного класу. Перший метод замінює Volley.newRequestQueue, який ми назвемо getRequestQueue. Нам також потрібен метод для додавання запитів в чергу, add, та метод чиєю відповідальністю буде відміна запитів, cancel. Наступний блок коду показує, як виглядає реалізація..
TAG це ключ, ідентифікатор об'єкту. В цьому конкретному випадку, він може бути чим завгодно:
Як ви вже знаєте, Volley забезпечує три стандартні типи запитів: StringRequest, ImageRequest, та JsonRequest. Наш додаток буде використовувати останній для збору даних погоди та передавати список випадкових зображень.
За замовчуванням, Volley ставить пріорітет NORMAL для запитів. Зазвичай це нормально, але в нашому додатку ми маємо два запити, що трохи різні і таким чином ми змушені мати різні пріорітети в черзі. Отримання даних погоди має бути з вищим пріоритетом аніж отримання URL випадкового зображення.
Ми мусимо кастомузувати клас JsonRequest. Створити новий клас з іменем CustomJsonRequest.java, та впевнитися, що він наслідує  JsonObjectRequest. Далі перевизначимо метод getPriority, як показано нижче.
Нарешті ми дісталися до найцікавішої частини цієї статті, де ми будемо писати реалізацію завантаження даних погоди. Кінцева точка запиту в нас:
Ви можете пройти за посиланням та переглянути, як буде виглядати відповідь на запит API у вигляді JSON. JSON містить простий об'єкт, result, що включає набір текстових констант, починаючи з температури та закінчуючи силою вітру та сходом сонця.
Почнемо з визначення змінних в класі  MainActivity:
Ви можете викликати MarsWeather.getInstance по за методом onCreate. Так як клас вже ініціалізований , ви не вимушені чекати на запуск методу onStart. Звичайно, ви маєте встановити посилання на елементи views в методі onCreate.
Після цього, настав час реалізувати метод loadWeatherData. Ми створюємо наш запит Volley та змінюємо пріоритет на HIGH. Далі запускаємо метод addз допоміжного класу щоб додати до черги запитів. Зверніть увагу на слухача результатів (result listener), тепер він впливає на інтерфейс.
Як бачите, метод бере мінімальне та максимальне значення температури, та показує користувачеві середнє значення. Я також реалізував простий метод для управління помилками.
Зараз нам потрібно викликати метод loadWeatherData в onCreate і готово. Додаток готовий показувати погоду на Марсі.
Тепер ми маємо ядро нашого додатку готовим і робочим, ми можемо сфокусуватися на зовнішньому вигляді. Ми збираємось зробити це додавши випадково обране зображення Марсу.
Нам буде потрібен Flickr API ключ щоб отримати зображення. Кінцева точка нашого зображення:
Як бачите, запит доволі простий. Ви просите у Flickr надати вам результат в форматі JSON (format=json), але ми не конкретизували JSON callback (nojsoncallback=1). Ви шукаєте зображення (method=flickr.photos.search) та теги в яких ви зацікавлені та якось відносяться до Марусу (tags=mars,planet,rover). Погляньте на документацію для отримання детальнішої інформації про запити URL.
Почнемо визначати необхідні змінні:
Далі, реалізуємо метод searchRandomImage:
Як ви можете бачити, Flickr надсилає JSONArray наповнений зображеннями. Метод. який я написав, для збору випадкового зображення генерує число від нуля до розміру масиву. Він відбирає зображення відносно індексу результату та будує URL для зображення згідно з цим посібником.
Як і раніше, ми повинні реалізувати метод для управління помилками:
І викликаємо метод searchRandomImage в onCreate не забудьте попіклуватися про виключні ситуації.
Тепер, оскільки ми маємо URL зображення, ми можемо показати його користувачеві. Як це зробити ви вже знаєте з попередньої статті.
В методі onResponse що ми написали в попередньому кроці, ми можемо отримати результат.
Можливо ви вже помітили, що примушуємо Volley отримувати випадкове зображення при кожному запуску додатку. Тепер зробимо щоб воно змінювалось кожен день, а на протязі дня залишалось незмінним.
Найпростіший спосіб досягнути  цього це скористатися SharedPreferences. Почнемо з визначення змінних, які нам знадобляться.
Далі, в onCreate методі, перед викликом searchRandomImage, ініціалізуємо mSharedPref.
Ідея в тому щоб зберігати день кожен раз як ми завантажуємо зображення. Звичайно ж, ми зберігаємо URL зображення разом з днем. Коли додаток запускається, проходить перевірка в SharedPreferences з сьогоднішній день. Якщо день співпадає ми використовуємо URL, який міститься у нас. В іншому випадку ми завантажуємо нове зображення та зберігаємо URL в SharedPreferences.
В searchRandomImage, після визначення imageUrl, додайте наступний код:
Метод onCreate, після додання змінної mSharedPref, тепер виглядає так:
Ось і все. Ваш додаток готовий. Завантажти вихідний код можна з репозиторію на  GitHub так виглядає завершений проект. Без виникнення помилок, краще спробувати зробити все самостійно.
Шрифт, що використовується в додатку, задає тон додатку. Почнемо зі зміни стандартного Roboto на більш стильний Lato light.
Створіть нову директорію з назвою fonts в assets. Якщо у вас немає директорії assets, створіть її на тому ж рівні що й java. Структура директорій має виглядати так app\src\main\assets\fonts.
Зкопіюйте Lato-light.ttf в fonts. В методі onCreate,  ви перевизначаєте шрифт за замовчуванням в тих views в яких ви хочете використовувати шрифт.
Притримуючись до гайдлайнів Android Material Design, ми можемо зробити наш status bar прозорим. Таким чином, фон буде частково видимим через status bar.
Ви досягаєте цього додавши трохи змін в тему. Змініть файл стилю v21\style.xml так:
Перевірте щоб в файлі AndroidManifest.xml була встановлена тема:
Ми пройшли довгий шлях. В першій статті, ми позали говорити про Volley та додатки з її використанням. В цій статі, ми розбиралися в практичній реалізації концепцій вивчених раніше протягом побудови додатку погоди для Марсу. Тепер ви мусите мати гарне уявлення про роботу бібліотеки Volley та про те на що вона здата.

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

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