MovieBox - pet-project для поиска, просмотра информации и отслеживания фильмов и сериалов. Цель проекта:
- разработка собственного дизайна;
- реализовать приятный UI и UX;
- реализовать проект с современным стеком технологий и решений;
- реализация многомодульного проекта;
- комбинация написания проекта и изучение и закрепление новых подходов и решений (см. итоги что из этого получилось);
Статус проекта: Временно на паузе
.
Есть идея реализации схожего по смыслу проекта, но с использованием Jetpack Compose, с продуманной архитектурой и исправлением недостатков этого проекта.
-
-
100% Kotlin + Coroutines - выполнение фоновых операций
-
Сеть
-
Coil - загрузка изображений
-
Klock - мультиплатформенная библиотека для работы с датой и временем
-
ViewBinding - управление и взаимодействие с элементами представления
-
Собственный дизайн
-
-
Архитектура
-
MVVM + MVI (только начал внедрять)
-
Android KTX - Jetpack Kotlin расширения
-
-
Внедрение зависимостей
- Koin - управление зависимостей
-
Статические анализаторы кода
- Ktlint - проверка и форматирование кода
-
Gradle
- Gradle Kotlin DSL и кастомные таски
-
Логгеры
-
Pretty Logger - легковесный и мощный логгер для Android
В проекте реализована модульная архитектура. Каждая группа экранов разбита на определенные feature-модули
. Данный подход позволяет достигнуть:
- лучшую гибкость по сравнению с подходом, где проект разбит на 3 модуля (presentation, domain, data);
- разделить код на группы и разрабатывать его изолированно;
- построить граф зависимостей так, чтобы получать доступ к классам можно было только при явной зависимости;
- улучшает навигацию по коду;
- чуть более быстрая компиляция проекта;
Такой подход был подробно описан в статье Multiple ways of defining Clean Architecture layers автором Igor Wojda. В данной статье автор сравнил разные подходы к разделению проекта на модули и выделил преимущества и недостатки каждого из них.
Ниже представлен граф зависимостей между существующими модулями:
-
:feature_navigation
- экраны навигации и настроек приложения; -
:feature_details
- все экраны, на которых отображаются детали элементов; -
:feature_search
- поиск и подбор с фильтрами; -
:feature_collections
- экраны с подборками (коллекциями); -
:feature_auth
- все, что касается авторизации в приложении; -
:lib_base
- базовые классы, общие методы, классы и ресурсы; -
:BuildSrc
- настройки проекта, библиотеки и их версии.
Обратите внимание, что модули реализованы как dynamic-feature модули, поэтому зависимости строятся наоборот. Тогда получается, что функциональные модули зависят от модуля приложения.
Каждый функциональный модуль содержит собственный набор слоев из Clean Architecture
.
Структура модулей app
и lib_base
отличается от структуры функциональных модулей и зависит от классов, которые в ней находятся.
Разработка проекта началась с идеи проекта, который бы мог упростить поиск фильмов и сериалов. Хотя похожих проектов довольно много, на которых все практикуются, но такие проекты как правило очень маленькие и с базовым функционалом, а я же не просто хотел попрактиковаться, я горел этой идей и хотел реализовать более крупное приложение, со своим дизайном и дополнительным функционалом.
Все началось с попыток нарисовать какой-то минимальный набор экранов и параллельная разработка начального функционала (список фильмов и детали фильма). Далее одновременно с набросками новых экранов, приложение обрастало новым функционалом и не редко переписывался старый функционал или перестраивался дизайн на каких-то экранах.
В итоге, в свободное время у меня стояло несколько задач:
-
придумать и разрабатывать дизайн дизайн;
-
разработка проекта (исправление багов и разработка нового функционала);
-
исследование и поиск новых решений;
Проект пережил множество различных глобальных изменений:
- избавление от множества активити, приближение к single-activity;
- разбиение проекта на feature delivery модули, что забрало очень много времени и добавило новых проблем;
- попытки реализации анимации смахивания экрана (похожая логика на экранах в YouTube);
- экспериментирование с Navigation Components для сохранения логики смахивания экрана жестом;
- миграция с Glide на Coil;
- миграция с Dagger на Koin;
- миграция на Gradle Kotlin DSL;
- использование ViewBinding (как только появилась) вместо Kotlin Synthetic;
- множественные изменения в дизайне (различные версии см. ниже), попытки разбиения его на различные компоненты, отделение иконок, шрифтов и цветов (создание дизайн системы);
- попытки оптимизации различных мест в проекте;
- реализация MVVM + MVI подхода для обработки различных состояний экрана;
- и т.д.;
В итоге, я считаю, что разработка проекта была положительным опытом. У меня все таки получилось реализовать свой дизайн почти в полном объеме, разбить проект на модули и сделать его более масштабируемым, а также использовать современные технологии и решения.
Однако, в силу того, что проект подвергался частым улучшениям и иногда сказывался недостаток времени, проект частично засорился, в нем есть места, которые могут быть улучшены или исправлены.
Ниже я опишу, что может быть улучшено или исправлено:
- построение архитектуры проекта на основе обычных модулей и разделение на core и feature модули;
- тестирование;
- использование функционала Coroutines и Flow на полную;
- построить зависимости для репозиториев на основе абстракций;
- оптимизация экран в xml, уменьшить вложенность;
- внедрить MVI и совместить с MVVM (как например, Roxy);
Есть несколько способов открыть проект:
Android Studio
->File
->New
->From Version control
->Git
- Ввести
https://github.com/majorkik/MovieBox.git
в поле URL и нажать кнопкуClone
- Запустить команду
git clone https://github.com/igorwojda/android-showcase.git
и клонировать проект к себе в директорию - Открыть
Android Studio
и выбратьFile | Open...
. Выбрать папку с клонированным проектом и нажать кнопкуOpen
.
Для запуска проекта, необходимо указать в файле local.properties
ряд ключей. Пример:
#Tmdb
keyTmdb="введите ключ"
keyTmdbv4="оставьте пустым"
#Youtube
youTubeKey="введите ключ"
#Trakt
secretKeyTrakTV="оставьте пустым"
keyTrakTv="оставьте пустым"
Ключ для TMDb можно взять на странице TMDb API Introduction.
Ключ для Youtube можно взять на странице Youtube API.
/gradle packageDebugUniversalApk
- собирает apk файлы вместе с динамическими модулями
/gradle ktlintDebugFormat
- анализ кода и его форматирование
/gradle ktlintDebugCheck
- анализ кода и поиск мест, которые могут быть отформатированы
/gradle dependencyUpdates
- отображает список библиотек и плагинов, которые используются в
проекте, их текущую версию и последнюю версию
Этот репозиторий находится под лицензией GNU v3
. Подробную информаци вы можете найти здесь или на официальном сайте.