Необходимо реализовать приложение, отображающее прогноз погоды.
- Отображение прогноза погоды за текущий день
- Отображение прогноза погоды за неделю
- Возможность увидеть прогноз погоды в текущем городе
- Возможность выбрать любой другой город, и узнать прогноз погоды в нем
В качестве API, для получения прогноза, можно использовать любой сервис; допускается использование бесплатных/ограниченных/пробных версий.
Пример: OpenWeatherMap API
Решения о дизайне остаются полностью на ваше усмотрение.
- Задание нужно выполнять на Kotlin.
- Выполненное задание нужно загрузить на github и отправить решение нам.
В качестве тестового задания было предложено создать мобильное приложение, отображающее прогноз погоды. Мы не ограничивали кандидатов в выборе стека технологий, предоставляя возможность использовать любые современные подходы и инструменты для написания кода. Единственным исключением был язык программирования Kotlin, который мы используем на нашем проекте.
В основном кандидаты использовали следующие инструменты:
- Работа с сетью:
Retrofit
,OkHttp
; - Многопоточность:
Kotlin Coroutines/Flow
,RxJava 2/3
; - View:
XML
,Jetpack Compose
; - Сериализаторы:
Kotlinx Serialization
,Gson
,Moshi
; - Навигация:
Activity
,Fragment
,Jetpack Navigation
.
Чистота кода:
- Соблюдение официальных рекомендаций по код стайлу в Kotlin;
- Использование понятных имен для переменных, функций, классов и модулей;
- Избегание дублирования кода путем выделения общих частей в отдельные функции или классы.
Архитектура проекта:
- В проекте возможно использовать как одномодульную, так и многомодульную архитектуру. Главный аспект – это разделение проекта на модули и пакеты;
- Применение подхода Clean Architecture для разделения уровней приложения на слои: Data, Domain и Presentation;
- Использование архитектурных паттернов в Presentation слое. Здесь можно выбрать одну из архитектур: MVP, MVVM или MVI;
- Применение различных инструментов для внедрения зависимостей (DI) и организация графа зависимостей в проекте.
Функционал описаный в требованиях:
- Весь функционал описаный в требованиях реализован;
- Отсутствуют краши и необработанные состояния при работе приложения.
Обработка ошибок:
- Обработаны события при сетевых запросах (отображение понятного текста ошибки и возможность повторить запрос);
- Использование заглушек (stub состояний), например, при отсутствии интернет-соединения
-
Создание проекта и разделение его на слои После создания проекта в Android Studio и настройки окружения, создаем отдельные модули или пакеты для разделения нашего приложения на слои (Data, Domain, Presentation).
Полезные ссылки:
-
Добавление интеграции API и организация Data слоя
Необходимо зарегистрироваться на сайте сервиса, который планируется использовать, и получить API-ключ. Для хранения API-ключа в приложении можно воспользоваться gradle плагином от Google. Также подключить библиотеки для работы с парсингом данных и HTTP-клиентом. Затем для получения прогноза погоды следует создать интерфейс с сетевыми запросами в Data слое, а также организовать модели данных для последующего использования в Domain слое.
-
Создание интерфейса пользователя
Здесь можно придерживаться рекомендаций Google и использовать подход Single Activity. Так как требования по дизайну остаются на усмотрение кандидатов, верстка может быть выполнена с использованием стандартных компонентов Android или с подключением библиотеки Material Design Components. Главное – учесть UX приложения, чтобы пользователю было удобно и информативно пользоваться вашим приложением. Так же для поддержки различных тем в приложении (например, ночная тема), следует настроить стили UI-компонентов и переопределить темы в папке values.
Полезные ссылки:
Android Developers: Guide to app architecture
Single activity: Why, when, and how
-
Получение текущего местоположения
Для определения текущего города необходимо получить разрешение на использование геолокации в приложении. В этом случае, следует прописать необходимые разрешения (permissions) в манифесте приложения, учитывая специфику различных версий Android, поддерживаемых вашим приложением.
Полезные ссылки:
-
Использования RecylcerView для отображение списков
Для отображения прогноза погоды на неделю, списка городов и т.д., потребуется использовать RecyclerView. В этом случае необходимо настроить адаптер для обработки данных внутри списка, а также создать ViewHolders для каждого типа представления, которое планируется отобразить в списке. Это минимальные действия для работы с динамическими списками, но данные могут обновляться, и не все из них подвержены изменению на экране внутри списка. Для эффективного изменения списка следует настроить DiffUtil и добавить его в адаптер. Использование DiffUtil улучшает производительность приложения, так как обновления списка происходят только в тех случаях, когда это действительно необходимо. Кроме того, DiffUtil обеспечивает корректное отображение анимаций при добавлении, удалении или изменении элементов списка, делая переходы более плавными и приятными для пользователя. Также для упрощения работы со списками можно использовать сторонние библиотеки, например, Epoxy, Groupie и т.д., которые помогут гибко и просто работать со сложными представлениями списков.
Полезные ссылки:
-
Организация Domain слоя
Когда верстка и список запросов готовы к использованию, необходимо организовать бизнес-логику между этими слоями. В Domain слое создаем модели данных, которые будут использоваться в бизнес-сценариях, а также добавляем при необходимости классы Interactors, Converters и UseCases. Они будут организовывать обработку полученных данных с сервера и передачу готовых данных для отображения в Presentation слое. Такое разделение помогает переиспользовать логику между различными сценариями, а также покрыть важный бизнес-функционал unit-тестами. Например, такими сценариями в нашем приложении могут выступать: добавление или удаление города из избранного, сортировка и группировка городов.
-
Формирования UI состояния и обработка ошибок
Это последний шаг, на котором нам следует организовать взаимодействие между Presenter/ViewModel и вашим View. В качестве примера предлагается использовать ViewModel в связке с LiveData, чтобы View могло подписаться на изменения состояний вашего UI и отрисовывать их. Также важно не забывать об обработке ошибок: когда мы отправляем запрос и происходит ошибка, мы должны сообщить пользователю, что что-то пошло не так. Одним из вариантов является показать Toast-сообщение с вашей сформированной ошибкой или полученной с сервера с конкретной причиной ошибки. Также у пользователя должна быть возможность повторить запрос (например, использовать для этого механизм pull-to-refresh или состояние заглушки со специальной кнопкой для повторения отправки запроса).
Полезные ссылки: