android studio структура приложения

Полный список

Для того, чтобы тестировать приложения, нам понадобится Android Virtual Device (AVD). Это эмулятор Android-смартфона, на который мы сможем устанавливать созданные нами приложения, и запускать их там. Давайте его создадим.

Урок обновлен 04.06.2017

На прошлом уроке мы установили среду разработки и Android SDK.

Теперь наконец-то мы можем создать наше первое приложение и посмотреть, как оно работает.

Т.е. в самом простом случае структура проекта такова:

Есть проект, и в нем есть модуль. При запуске проекта запускается модуль и мы получаем Android-приложение, которое создано в этом модуле.

В этом случае: один проект = одно Android-приложение (один модуль).

Но в одном проекте может быть несколько модулей. Да и проектов можно создать несколько.

Здесь в первом проекте созданы два модуля, а во втором проекте – три модуля.

При запуске какого-либо проекта необходимо будет указать, какой именно модуль вы хотите запустить. И каждый модуль является отдельным Android-приложением.

Т.е. в этом случае: один проект = несколько Android-приложений (несколько модулей).

Пока не будем вдаваться в детали, какая из предложенных схем лучше и удобнее. Для прохождения уроков можно создать один проект, и в нем создавать модули для каждого урока. Либо можно создавать отдельный проект, например, на каждые 10 уроков. Можно вообще создавать отдельный проект на каждый урок.

Я думаю, что мы начнем с варианта: один проект под все уроки. А со временем, как освоитесь, сами решите, какой вариант вам удобнее.

Давайте создадим проект. Открываем Android Studio. Ярлык для запуска должен быть в меню пуск. Либо вы можете открыть папку, куда устанавливали Android Studio на прошлом уроке. В подпапке bin должен быть EXE-файл.

010.png.pagespeed.ce.b BgaCCtIH

Открылась среда разработки. Жмем Start a new Android Studio project.

Появилось окно создания проекта. Давайте заполнять.

Application name – имя проекта. Оно будет отображаться в списке проектов при открытии Android Studio. Напишем здесь Android lessons (т.е. Android уроки).

Company Domain – имя сайта, пишем startandroid.ru.

Package name – это понятие из Java, подробно можно посмотреть здесь. Вкратце – это префикс для имени классов нашего приложения. Как видите, пакет автоматически составился из имени сайта и имени проекта. Его всегда можно отредактировать вручную нажав на ссылку edit справа.

Project location – папка на компе, где будут находиться все файлы проекта. Мы на прошлом уроке создавали папку android, куда установили Android Studio и SDK. Там же создайте папку AndroidStudioProjects – в этой папке будем хранить все проекты Android Studio. И в ней создайте папку Androidlessons для нашего текущего проекта.

Скорее всего сейчас ничего не понятно. Это нормально, не волнуйтесь. В каждом уроке я буду подсказывать, что заполнять в этих полях, и со временем понимание придет.

Визард спрашивает под какую платформу будем кодить и Minimum SDK (минимальная версия Android, на которой можно будет запустить приложение). Оставляем все как есть.

040.png.pagespeed.ce.jKXgBEyg5T

Визард может подгрузить необходимые ему компоненты.

050.png.pagespeed.ce.jPHH1WIM0K

Далее выберите Empty Activity.

Здесь ничего не меняем. Пока что нам нет необходимости знать, зачем все это нужно.

Далее открывается студия. После открытия, она может показывать подсказки.

Если они вам не нужны, выключайте чекбокс.

Жмем Close.

100.png.pagespeed.ce.IXGmkbnAbs

Но снизу виден прогресс бар. Это означает, что еще выполняются какие то действия, и надо подождать.

И в итоге проект открывается

110.png.pagespeed.ce.8TBKMTuZGj

Нам сразу открыты на редактирование некоторые файлы. В них мы ничего менять не будем, в этом пока нет необходимости.

В левой части мы видим слово app – это модуль. По умолчанию при создании проекта создается модуль app. Нам он не интересен, т.к. мы будем создавать свои модули. Но пусть он остается, удалять его я вам не советую. Тот визард, который мы только что прошли при создании проекта, в основном касался как раз этого модуля.

Итак, проект создан. Теперь создадим в проекте свой модуль. Повторюсь, что почти для каждого урока мы будем создавать модуль в этом проекте. Сейчас создадим модуль (приложение) для этого текущего урока. Эта процедура будет частично похожа на создание проекта, но с небольшими отличиями.

Тип модуля выбираем Phone and Tablet Application

640x433x120.png.pagespeed.ic.02haZhxz b

640x433x130.png.pagespeed.ic.Sf KmB6LsG

Application/Library name – непосредственно имя приложения, которое будет отображаться в списке приложений в смартфоне. Пишем тут FirstProject.

Module name – это название модуля. Т.е. это название будет отображаться слева в списке модулей, там, где сейчас есть app. Давайте придумаем шаблон для названия модулей.

Package name – имя пакета отредактируем вручную, нажав edit справа. Оставим там ru.startandroid и добавим точку и имя модуля.

Minimum SDK оставляйте без изменений.

Далее выберите Empty Activity.

Здесь ничего не меняем

640x433x150.png.pagespeed.ic.F

Жмем Finish и ждем.

160.png.pagespeed.ce.HZWBF0vYKA

Можно раскрыть этот модуль и посмотреть его содержимое.

Вкратце пройдемся по интересующим нас элементам

Файл AndroidManifest.xml – манифест или конфиг-файл приложения

В папке java и ее подпапках будет весь, написанный нами, код приложения

Папка res используется для файлов-ресурсов различного типа.

Все это мы будем в дальнейшем использовать, и станет понятнее, что и зачем нужно.

Давайте наконец-то запустим наше первое приложение! Для этого надо выбрать соответствующий ему модуль в выпадающем списке сверху

И жмем (чуть правее списка) кнопку с зеленым треугольником (либо комбинацию Shift+F10).

Чтобы запустить приложение, нужно какое-нить реальное Android-устройство или эмулятор.

У нас пока не на чем запускать приложение. Можете подключить шнуром реальное устройство, и оно здесь появится (если не возникнет проблем с драйверами или настройками устройства).

Либо можно создать эмулятор. Жмем Create New Virtual Device

Здесь можно выбрать форм-фактор устройства. Оставляйте то, что выбрано по умолчанию.

Жмем Next

Далее переходите на вкладку x86 Images и там должен быть образ, в названии которого нет слова Download. Т.е. он уже загружен и мы можем его использовать.

В данном случае на эмулятор будет установлен Android версии 7.1.1. Если вам нужна другая версия, то загружайте ее и используйте.

Далее нам предлагают указать название эмулятора и поменять его настройки. Оставляем все как есть

640x461x210.png.pagespeed.ic.DJ svoZStV

Жмем Finish

В итоге в списке устройств появляется только что созданный эмулятор и мы можем использовать его для запуска приложения.

Жмем Ok

Через какое-то время (вплоть до нескольких минут) появится эмулятор

И в нем начнет запускаться Android

И в итоге запустится наше приложение

Т.е. вы создали и запустили ваше первое приложение, с чем вас и поздравляю) Впереди сотни таких приложений и запусков.

Если эмулятор не показал ваше приложение, то убедитесь, что Android Studio «видит» этот эмулятор. Для этого снизу слева нажмите вкладку Android Monitor

260.png.pagespeed.ce.Fc ql3RRuK

И в списке устройств чуть выше должен быть виден эмулятор Nexus_5X_API_25

Если эмулятор есть в списке, а приложение не отобразилось, то попробуйте снова запустить приложение, нажав зеленый треугольник (Shift+F10).

Если эмулятора в списке нет, то закройте эмулятор и попробуйте снова запустить приложение.

Этот урок был обновлен в июне 2017. А многие последующие уроки были написаны аж в 2011-2012. Поэтому скриншоты в них могут отличаться от ваших. Это нормально.

Также, должен предупредить, что я делал и тестировал первые уроки под Android версии 2.3.3. Это указано в начале уроков. Но это вовсе не означает, что уроки уже безнадежно устарели и читать их смысла нет никакого. Код под 2.3.3 и 7.1.1 в подавляющем большинстве случаев абсолютно один и тот же. В новых версиях Android добавляются новые компоненты, а прошлые обычно остаются без изменений и достаточно редко меняются или объявляются устаревшими.

Если у вас открыт проект и вы хотите снова увидеть стартовое окно Android Studio, в меню выберите File > Close Project.

Вы увидите стартовое окно, слева будет список ваших проектов.

Если у вас имя пользователя русскими буквами, то могут возникнуть проблемы. Как их решить, можно прочесть на форуме в ветке этого урока.

Если строка выше не помогла, то попробуйте еще такое решение.

На следующем уроке будем добавлять в наше приложение различные элементы и менять их свойства.

Присоединяйтесь к нам в Telegram:

— в канале StartAndroid публикуются ссылки на новые статьи с сайта startandroid.ru и интересные материалы с хабра, medium.com и т.п.

— в чатах решаем возникающие вопросы и проблемы по различным темам: Android, Kotlin, RxJava, Dagger, Тестирование

— ну и если просто хочется поговорить с коллегами по разработке, то есть чат Флудильня

— новый чат Performance для обсуждения проблем производительности и для ваших пожеланий по содержанию курса по этой теме

Источник

Структура проекта в Android Studio

В этой статье мы рассмотрим структуру проекта в Android Studio и познакомимся с компонентами любого современного Android приложения.

Когда мы генерируем новый Android проект с помощью Android Studio (например, создание простого Hello Android приложения), автоматически генерируется множество файлов и папок. Давайте рассмотрим каждый из основных компонентов и директорий только что созданного проекта:

Так выглядит пустой, только что сгенерированный Android проект в Android Studio.

Как видно из картинки, Android проект представлен 2 корневыми папками: app и Gradle Scripts. Папка app включает 3 подпапки:

А теперь подробнее о каждой папке:

Что такое AndroidManifest.xml файл

Папка java в Android проекте

Папка java содержит исходный код приложения. Классы могут быть расположены в различных пакетах, но обязательно внутри папки java.

Зачем нужна папка res

В папке res расположены все используемые приложением ресурсы, включая изображения, различные xml файлы, анимации, звуковые файлы и многие другие. Внутри папки res эти все ресурсы распределены по своим папкам:

Сценарии Gradle в Android Studio

Сегодня мы рассмотрели основные компоненты структуры проекта в Android Studio.

Источник

? Разработка приложений на Android с нуля: установка среды разработки

aea67a943b2711f144650f599ab4af35

За последний год 53% интернет-трафика пришло с мобильных устройств, а приложения для Android используются значительно чаще прочих – до 71% смартфонов и планшетов работают под управлением самой популярной ОС в мире.

Знание Kotlin очень востребовано у работодателей. Диаграмма показывает соотношение вызовов на интервью владеющих разными языками программирования специалистов:

047d66cf86be441ee37493d9fad2e6f3Источник: Hired.

В то же время Kotlin – не самый популярный язык среди программистов, следовательно конкуренция среди владеющих им специалистов значительно меньше:

c13430bea81610b83a925e80ec9e307cИсточник: Hired.

С какого языка программирования начать

Несмотря на более высокую востребованность Kotlin, если вы совсем новичок в программировании, начинать стоит с изучения Java. Тому есть несколько причин:

Тем не менее, в 2019 году Google объявил Kotlin как предпочтительный язык для разработки мобильных приложений на Android.

Структура приложений на Android

Приложение для Андроида состоит из четырех основных блоков, каждый из которых живет своей жизнью (имеет независимый жизненный цикл) – это означает, что создается и удаляется каждый компонент по-разному.

Компонентов одного вида может быть несколько, и они тоже работают независимо друг от друга.

1. Активности (activities) – это части приложения, которые видит (есть интерфейс) и с которыми взаимодействует пользователь. Например, в мессенджере отображаются непрочитанные сообщения, и пользователь что-то с ними делает.

2. Службы (services) – этот блок осуществляет свои действия на фоне работы с активностями или с другими приложениями. Можно выделить два типа: начатые, которые работают пока не завершат определенное действие (музыкальный проигрыватель, синхронизация), а также обязанные сервисы (bound services) – они запускаются по указанию системы или другого приложения.

3. Широковещательные приемники (Broadcast receivers) – это компоненты, которые постоянно сканируют указанную область (систему, другие приложение, ваше приложение) и доставляют в приложение сообщения об отслеживаемых изменениях.

Эти блоки могут запускаться системой (уведомление о низком заряде батареи), а также другими приложениями. Они, например, уведомляют другие приложения, что определенный файл был скачан и теперь доступен для использования.

4. Контент-провайдеры управляют данными приложения. Другие приложения могут запрашивать или изменять какие-то данные в хранилищах контент-провайдеров с их разрешения. Например, контент-провайдер системы Android по запросам от других приложений предоставляет им информацию о списке контактов пользователя.

Этот компонент также может использоваться для чтения и записи приватных данных, которые не предназначены для передачи другому приложению.

В системе каждое приложение работает в отдельном процессе, поэтому чтобы активировать какой-то из компонентов, используются такие объекты как намерения (intents). Они активируют сервисы, активности и широковещательные приемники.

Ресурсы – некодовые компоненты, вроде картинок, звуков, макетов и т.д. Они хранятся в отдельных файлах.

Базовые инструменты для начала

1. Android Studio – интегрированная среда разработки (IDE) для создания андроид-приложений. В ней вы найдете все необходимое: редактор кода, быстрый и многофункциональный эмулятор, образцы кода, интеграцию с GitHub, фреймворки и инструменты для тестирования, встроенную поддержку для облачной платформы Google и т.д.

Чтобы IDE работала быстро, рекомендуется запускать ее на: Windows 7, 8, или 10 (32-bit или 64-bit), Mac OS X от 10.10 (Yosemite) до 10.14 (Mojave), Linux (Ubuntu 14.04 LTS), Chrome OS.

2. Java Development Kit – это набор инструментов, которые помогают писать и запускать код на Java. Туда входят, например, компилятор и дебаггер.

3. Android-устройство – не обязательно телефон. Это может быть планшет, смарт-часы, телевизор, холодильник или какие-то другие умные вещи.

Если под рукой нет нужного устройства, для запуска приложений можно использовать виртуальный эмулятор. Он представляет собой программу, которая запускается на компьютере, но выглядит и ведет себя как физическое устройство.

Создаем приложение в Android Studio

Инсталлируем среду разработки в Windows

3. Когда студия запускается, просто нажимаем несколько раз «next», там все нужное уже отмечено.

4. Когда у вас появляется окошко «Import Android Studio Settings», выбираем «do not import settings».

5. В «Install type» выбираем «Standard».

6. Выбираем светлую или темную тему.

8. Когда появилось окошко для начала нового проекта, нажимаем «Configure», а потом «Settings».

9. В открывшемся окне слева выбираем «System settings», а потом «Andoid SDK». Тут рекомендуется выбрать среды для всех версий Android, так как они пригодятся, когда вы будете создавать приложения под разные устройства. Если у вас не хватает памяти, можно не скачивать – для первого раза они не понадобятся.

Структура проекта в Android Studio

Каждый проект делится на модули, которые имеют отдельные файлы, настройки, функциональность. В проекте может быть один модуль или множество. Они по отдельности разрабатываются, тестируются и очищаются от неполадок.

Когда вы впервые создаете приложение, в новом проекте сразу появятся модули: «Android app module» и «Gradle».

81bc3e44df253c34f93e02316445493cИсточник: Developer. Android

«Android app module» состоит из следующих элементов:

«Gradle» – это система сборки приложения. Она настраивается отдельно для каждого приложения.

Можно добавить следующие модули:

Как добавить новые модули: File —> New —> New Module.

Как запустить простое приложение с «Hello world»

1. Открываем Android Studio.

2. В первом же окне вам нужно нажать «Start a new Android Studio project».

3. Далее необходимо выбрать тип устройства (телефон, часы, телевизор, автомобиль, интернет вещей). В каждом есть различные шаблоны. Для начала выбираем «Empty Activity» и нажимаем «next».

4. Теперь появляется окошко, где выбирается название проекта, язык и место на диске, куда сохранится проект.

Остальное пока менять не нужно, но уже в реальном приложении в «package name» вы сможете вписать свое доменное имя вместо «com.example».

Что касается «minimum API level», то приложения разработанные на более старой версии будут доступны для большего количества устройств, а на более новых легче работать.

5. Терпеливо ждем, пока подгрузятся все файлы нового проекта. Следующие будут открываться быстрее.

Запускаем на эмуляторе

Без виртуального устройства приложение не запустится. Поэтому создаем его в Android Studio:

Запускаем на реальном устройстве

1. В настройках устройства нужно найти «Параметры разработчика —> Отладка USB».

2. Убедитесь, что на на вашем компьютере установлен «USB Driver».

3. Подключите андроид-устройство через порт USB.

4. В Android Studio в панели инструментов выберите ваше устройство.

e2a04b5cc5b29121a289de13d6a5399d

5. Нажмите «Run». Приложение загрузится и запустится.

Если вас интересует полное погружение в профессию разработчика приложений для Android и обучение, после которого сразу можно выйти на рынок и получить оффер, стоит обратить внимание на факультет Андроид-разработки образовательной платформы GeekBrains.

В течение года под руководством экспертов-практиков вы освоите языки программирования Java и Kotlin, основные компоненты и элементы пользовательского интерфейса, жизненный цикл компонентов Activity и Fragment, работу с базами данных, архитектурные шаблоны проектирования, работу со сторонними библиотеками и тестирование приложений.

Успешно завершившим курс студентам выдается диплом о профессиональной переподготовке, а кроме того онлайн-академия оказывает им помощь в трудоустройстве.

Источник

Руководство по организации архитектуры Android приложения

Привет, Хабр! Представляю вашему вниманию вольный перевод «Руководство по архитектуре приложения (Guide to app architecture)» из JetPack. Все замечания по переводу прошу оставлять в комментариях, и они будут исправлены. Так же для всех будут полезны комментарии от тех кто использовал представленную архитектуру с рекомендациями её использования.

Это руководство охватывает лучшие практики и рекомендуемую архитектуру для создания надежных приложений. Эта страница предполагает базовое знакомство с Android Framework. Если вы новичок в разработке приложений для Android, ознакомьтесь с нашими руководствами для разработчиков, чтобы начать работу и узнать больше о концепциях, упомянутых в этом руководстве. Если вы интересуетесь архитектурой приложений и хотели бы ознакомиться с материалами этого руководства с точки зрения программирования на Kotlin, ознакомьтесь с курсом Udacity «Разработка приложений для Android с помощью Kotlin».

Опыт пользователя мобильного приложения

В большинстве случаев настольные приложения имеют единую точку входа с рабочего стола или программы запуска, а затем запускаются как единый монолитный процесс. Приложения на Android имеют гораздо более сложную структуру. Типичное приложение для Android содержит несколько компонентов приложения, включая Activities, Fragments, Services, ContentProviders и BroadcastReceivers.

Вы объявляете все или некоторые из этих компонентов приложения в манифесте приложения. Затем ОС Android использует этот файл, чтобы решить, как интегрировать ваше приложение в общий пользовательский интерфейс устройства. Учитывая, что правильно написанное приложение Android содержит несколько компонентов, и пользователи часто взаимодействуют с несколькими приложениями за короткий промежуток времени, приложения должны адаптироваться к различным типам рабочих процессов и задач, управляемых пользователями.

Например, рассмотрим, что происходит, когда вы делитесь фотографией в своем любимом приложении для социальных сетей:

Помните, что мобильные устройства также ограничены в ресурсах, поэтому в любой момент операционная система может уничтожить некоторые процессы приложения, чтобы освободить место для новых.

Учитывая условия этой среды, компоненты вашего приложения могут запускаться по отдельности и не по порядку, а операционная система или пользователь могут уничтожить их в любое время. Поскольку эти события не находятся под вашим контролем, вы не должны хранить какие-либо данные или состояния в ваших компонентах приложения, и ваши компоненты приложения не должны зависеть друг от друга.

Общие архитектурные принципы

Если вы не должны использовать компоненты приложения для хранения данных и состояния приложения, как вы должны разрабатывать свое приложение?

Разделение ответственности

Самый важный принцип, которому нужно следовать, — это разделение ответственности. Распространена ошибка, когда вы пишете весь свой код в Activity или Fragment. Это классы пользовательского интерфейса которые должны содержать только логику обрабатывающую взаимодействие пользовательского интерфейса и операционной системы. Как можно больше разделяя ответственность в этих классах (SRP), вы можете избежать многих проблем, связанных с жизненным циклом приложения.

Управление пользовательским интерфейсом из модели

Другой важный принцип заключается в том, что вы должны управлять своим пользовательским интерфейсом из модели, предпочтительнее из постоянной модели. Модели — это компоненты, которые отвечают за обработку данных для приложения. Они не зависят от объектов View и компонентов приложения, поэтому на них не влияют жизненный цикл приложения и связанные с ним проблемы.

Постоянная модель идеально подходит по следующим причинам:

Рекомендуемая архитектура приложения

Этот раздел демонстрирует как структурировать приложение, используя компоненты архитектуры, работая в сквозном сценарии использования.

Примечание. Невозможно иметь один способ написания приложений, который лучше всего подходит для каждого сценария. При этом рекомендованная архитектура является хорошей отправной точкой для большинства ситуаций и рабочих процессов. Если у вас уже есть хороший способ написания приложений для Android, соответствующий общим архитектурным принципам, менять его не стоит.

Представьте, что мы создаем пользовательский интерфейс, который показывает профиль пользователя. Мы используем приватный API и REST API для извлечения данных профиля.

Обзор

Для начала рассмотрим схему взаимодействия модулей архитектуры готового приложения:

image loader

Обратите внимание, что каждый компонент зависит только от компонента на один уровень ниже его. Например, Activity и Fragments зависят только от модели представления. Repository является единственным классом, который зависит от множества других классов; в этом примере хранилище зависит от постоянной модели данных и удаленного внутреннего источника данных.

Этот дизайн паттерн создает последовательный и приятный пользовательский опыт. Независимо от того, вернется пользователь к приложению через несколько минут после его закрытия или спустя несколько дней, он мгновенно увидит информацию пользователя о том, что приложение сохраняется локально. Если эти данные устарели, модуль хранилища приложения начинает обновлять данные в фоновом режиме.

Создаём пользовательский интерфейс

Для управления пользовательским интерфейсом наша модель данных должна содержать следующие элементы данных:

Объект ViewModel предоставляет данные для определенного компонента пользовательского интерфейса, таких как fragment или Activity, и содержит бизнес-логику обработки данных для взаимодействия с моделью. Например, ViewModel может вызывать другие компоненты для загрузки данных и может пересылать запросы пользователей на изменение данных. ViewModel не знает о компонентах пользовательского интерфейса, поэтому на него не влияют изменения конфигурации, такие как воссоздание Activity при повороте устройства.

Теперь мы определили следующие файлы:

Теперь, когда у нас есть эти модули кода, как мы их соединяем? После того как пользовательское поле установлено в классе UserProfileViewModel, нам нужен способ информировать пользовательский интерфейс.

Примечание. SavedStateHandle позволяет ViewModel получить доступ к сохраненному состоянию и аргументам связанного фрагмента или действия.

Теперь нам нужно сообщить нашему Фрагменту, когда получен пользовательский объект. Вот тут-то и появляется компонент архитектуры LiveData.

LiveData — это наблюдаемый держатель данных. Другие компоненты в вашем приложении могут отслеживать изменения объектов, используя этот держатель, не создавая явных и жестких путей зависимости между ними. Компонент LiveData также учитывает состояние жизненного цикла компонентов вашего приложения, таких как Activities, Fragments и Services, и включает логику очистки для предотвращения утечки объектов и чрезмерного потребления памяти.

Примечание. Если вы уже используете такие библиотеки, как RxJava или Agera, вы можете продолжать использовать их вместо LiveData. Однако при использовании библиотек и подобных подходов убедитесь, что вы правильно обрабатываете жизненный цикл своего приложения. В частности, убедитесь, что вы приостановили свои потоки данных, когда связанный LifecycleOwner остановлен, и уничтожили эти потоки, когда связанный LifecycleOwner был уничтожен. Вы также можете добавить артефакт android.arch.lifecycle: реактивные потоки, чтобы использовать LiveData с другой библиотекой реактивных потоков, такой как RxJava2.

Теперь модифицируем UserProfileFragment для наблюдения за данными во ViewModel и для обновления пользовательского интерфейса в соответствии с изменениями:

Каждый раз, когда данные профиля пользователя обновляются, вызывается обратный вызов onChanged(), и пользовательский интерфейс обновляется.

Получение данных

В этом примере мы предполагаем, что наш backend предоставляет REST API. Мы используем библиотеку Retrofit для доступа к нашему backend, хотя вы можете использовать другую библиотеку, которая служит той же цели.

Вместо этого наша ViewModel делегирует процесс извлечения данных новому модулю, хранилищу.

Модули репозитория обрабатывают операции с данными. Они предоставляют чистый API, так что остальная часть приложения может легко получить эти данные. Они знают, откуда взять данные и какие вызовы API следует выполнять при обновлении данных. Вы можете рассматривать репозитории как посредники между различными источниками данных, такими как постоянные модели, веб-службы и кэши.

Хотя модуль хранилища выглядит ненужным, он служит важной цели: он абстрагирует источники данных от остальной части приложения. Теперь наш UserProfileViewModel не знает, как извлекаются данные, поэтому мы можем предоставить модели представления данные, полученные из нескольких различных реализаций извлечения данных.

Примечание. Мы упустили случай сетевых ошибок для простоты. Для альтернативной реализации, которая выставляет ошибки и статус загрузки, см. Приложение: раскрытие статуса сети.

Управление зависимостями между компонентами

Для решения этой проблемы вы можете использовать следующие шаблоны проектирования:

Эти шаблоны позволяют вам масштабировать ваш код, потому что они предоставляют четкие шаблоны для управления зависимостями без дублирования или усложнения кода. Кроме того, эти шаблоны позволяют быстро переключаться между тестовыми и производственными реализациями выборки данных.

Подключите ViewModel и хранилище

Теперь мы модифицируем наш UserProfileViewModel для использования объекта UserRepository :

Кеширование

Эта конструкция является неоптимальной по следующим причинам:

Постоянные данные

Используя нашу текущую реализацию, если пользователь поворачивает устройство или уходит и немедленно возвращается в приложение, существующий пользовательский интерфейс становится видимым мгновенно, потому что хранилище извлекает данные из нашего кеша в памяти.

Тем не менее, что произойдет, если пользователь покинет приложение и вернется через несколько часов после того, как ОС Android завершит процесс? Полагаясь на нашу текущую реализацию в этой ситуации, нам нужно снова получить данные из сети. Этот процесс обновления не просто плохой пользовательский опыт; это также расточительно, потому что он потребляет ценные мобильные данные.

Вы можете решить эту проблему, кэшируя веб-запросы, но это создает ключевую новую проблему: что произойдет, если те же пользовательские данные будут отображены в запросе другого типа, например при получении списка друзей? Приложение будет отображать противоречивые данные, что в лучшем случае сбивает с толку. Например, наше приложение может отображать две разные версии данных одного и того же пользователя, если пользователь отправлял запрос списка друзей и однопользовательский запрос в разное время. Наше приложение должно было бы выяснить, как объединить эти противоречивые данные.

Правильный способ справиться с этой ситуацией — использовать постоянную модель. Нам на помощь приходит библиотека сохранения постоянных данных (БД) Room.

Room — это библиотека объектно-реляционного отображения (object-mapping), которая обеспечивает локальное сохранение данных с минимальным стандартным кодом. Во время компиляции он проверяет каждый запрос на соответствие вашей схеме данных, поэтому неработающие запросы SQL приводят к ошибкам во время компиляции, а не к сбоям во время выполнения. Room абстрагируется от некоторых базовых деталей реализации работы с необработанными таблицами SQL и запросами. Это также позволяет вам наблюдать за изменениями в данных БД, включая коллекции и запросы на соединение, выставляя такие изменения с помощью объектов LiveData. Он даже явно определяет ограничения выполнения, которые решают общие проблемы с потоками, такие как доступ к хранилищу в основном потоке.

Примечание. Если ваше приложение уже использует другое решение, такое как объектно-реляционное отображение SQLite (ORM), вам не нужно заменять существующее решение на Room. Однако, если вы пишете новое приложение или реорганизуете существующее приложение, мы рекомендуем использовать Room для сохранения данных вашего приложения. Таким образом, вы можете воспользоваться возможностями абстракции библиотеки и проверки запросов.

Чтобы использовать Room, нам нужно определить нашу локальную схему. Сначала мы добавляем аннотацию @Entity в наш класс модели данных User и аннотацию @PrimaryKey в поле id класса. Эти аннотации помечают User как таблицу в нашей базе данных, а id — как первичный ключ таблицы:

Затем мы создаем класс базы данных, реализуя RoomDatabase для нашего приложения:

Обратите внимание, что UserDatabase является абстрактной. Библиотека Room автоматически обеспечивает реализацию этого. Подробности смотрите в документации по Room.

Теперь нам нужен способ вставки пользовательских данных в базу данных. Для этой задачи мы создаем объект доступа к данным (DAO).

Обратите внимание, что метод load возвращает объект типа LiveData. Room знает, когда база данных изменена, и автоматически уведомляет всех активных наблюдателей об изменении данных. Поскольку Room использует LiveData, эта операция эффективна; он обновляет данные только при наличии хотя бы одного активного наблюдателя.

Примечание: Room проверяет недействительность на основе модификаций таблицы, что означает, что она может отправлять ложные положительные уведомления.

Если пользователи вернутся через несколько дней, то приложение использующее эту архитектуру, вполне вероятно, покажет устаревшую информацию, пока хранилище не получит обновленную информацию. В зависимости от вашего варианта использования вы можете не отображать устаревшую информацию. Вместо этого вы можете отобразить данные-заполнители (placeholder data), которые показывают фиктивные значения и указывают, что ваше приложение в настоящее время загружает и загружает актуальную информацию.

Единственный источник правды

Обычно разные конечные точки REST API возвращают одни и те же данные. Например, если у нашего бэкэнда есть другая конечная точка, которая возвращает список друзей, один и тот же пользовательский объект может исходить из двух разных конечных точек API, возможно, даже с использованием разных уровней детализации. Если бы UserRepository возвращал ответ от запроса Webservice как есть, без проверки согласованности, наши пользовательские интерфейсы могли бы показывать запутанную информацию, потому что версия и формат данных из хранилища зависели бы от последней вызванной конечной точки.

Показывать прогресс операции

Мы можем использовать одну из следующих стратегий для отображения согласованного статуса обновления данных в пользовательском интерфейсе независимо от того, откуда поступил запрос на обновление данных:

Протестируйте каждый компонент

В разделе о разделении интересов мы упомянули, что одним из ключевых преимуществ следования этому принципу является тестируемость.

В следующем списке показано, как протестировать каждый модуль кода из нашего расширенного примера:

Лучшие практики

Программирование — это творческое поле, и создание приложений для Android не является исключением. Существует много способов решения проблемы, будь то передача данных между несколькими действиями или фрагментами, извлечение удаленных данных и их локальное сохранение в автономном режиме, или любое количество других распространенных сценариев, с которыми сталкиваются нетривиальные приложения.

Хотя следующие рекомендации не являются обязательными, наш опыт показывает, что их выполнение делает вашу кодовую базу более надежной, тестируемой и поддерживаемой в долгосрочной перспективе:

Избегайте обозначения точек входа вашего приложения — таких как действия, службы и широковещательные приемники — в качестве источников данных.

Вместо этого они должны координировать свои действия только с другими компонентами, чтобы получить подмножество данных, относящихся к этой точке входа. Каждый компонент приложения довольно недолговечен, в зависимости от взаимодействия пользователя с его устройством и общего текущего состояния системы.

Создайте четкие границы ответственности между различными модулями вашего приложения.

Например, не распространяйте код, который загружает данные из сети, по нескольким классам или пакетам в вашей кодовой базе. Точно так же не определяйте множественные несвязанные обязанности — такие как кэширование данных и связывание данных — в одном классе.

Выставляйте как можно меньше от каждого модуля.

Не поддавайтесь соблазну создать ярлык «всего один», который раскрывает детали внутренней реализации из одного модуля. Вы можете выиграть немного времени в краткосрочной перспективе, но затем вы будете нести технический долг много раз по мере развития вашей кодовой базы.

Подумайте, как сделать каждый модуль тестируемым изолированно.

Например, наличие четко определенного API для извлечения данных из сети облегчает тестирование модуля, который сохраняет эти данные в локальной базе данных. Если вместо этого вы смешиваете логику этих двух модулей в одном месте или распределяете свой сетевой код по всей базе кода, тестирование становится намного сложнее — в некоторых случаях даже не невозможным.

Сосредоточьтесь на уникальном ядре вашего приложения, чтобы оно выделялось среди других приложений.

Не изобретайте велосипед заново, снова и снова записывая один и тот же шаблон. Вместо этого сосредоточьте свое время и энергию на том, что делает ваше приложение уникальным, и позвольте компонентам архитектуры Android и другим рекомендуемым библиотекам справиться с повторяющимся образцом.

Сохраняйте как можно больше актуальных и свежих данных.

Таким образом, пользователи могут наслаждаться функциональностью вашего приложения, даже если их устройство находится в автономном режиме. Помните, что не все ваши пользователи пользуются постоянным высокоскоростным подключением.

Назначьте один источник данных единственным источником истинны.

Всякий раз, когда вашему приложению требуется доступ к этому фрагменту данных, оно всегда должно происходить из этого единственного источника истины.

Дополнение: раскрытие статуса сети

В приведенном выше разделе рекомендуемой архитектуры приложения мы пропустили сетевые ошибки и состояния загрузки для упрощения фрагментов кода.

В этом разделе показано, как отобразить состояние сети с помощью класса Resource, который инкапсулирует как данные, так и их состояние.

Следующий фрагмент кода предоставляет пример реализации Resource:

На следующей диаграмме показано дерево решений для NetworkBoundResource :

image loader

Он начинается с наблюдения за базой данных для ресурса. Когда запись загружается из базы данных в первый раз, NetworkBoundResource проверяет, является ли результат достаточно хорошим, чтобы его можно было отправить, или его нужно получить из сети заново. Обратите внимание, что обе эти ситуации могут возникать одновременно, учитывая, что вы, вероятно, хотите показывать кэшированные данные при обновлении их из сети.

Если сетевой вызов завершается успешно, он сохраняет ответ в базе данных и повторно инициализирует поток. В случае сбоя сетевого запроса NetworkBoundResource отправляет сбой напрямую.

Примечание. После сохранения новых данных на диск мы повторно инициализируем поток из базы данных. Однако обычно нам не нужно этого делать, потому что сама база данных отправляет изменения.

Имейте в виду, что полагаться на базу данных для отправки изменений включает в себя использование связанных побочных эффектов, что не очень хорошо, потому что неопределенное поведение этих побочных эффектов может произойти, если база данных не отправит изменения, потому что данные не изменились.

Кроме того, не отправляйте результаты, полученные из сети, поскольку это нарушит принцип единого источника истины. В конце концов, возможно, база данных содержит триггеры, которые изменяют значения данных во время операции сохранения. Точно так же не отправляйте `SUCCESS` без новых данных, потому что тогда клиент получит неверную версию данных.

В следующем фрагменте кода показан открытый API, предоставленный классом NetworkBoundResource для его подклассов:

Обратите внимание на следующие важные детали определения класса:

После создания NetworkBoundResource мы можем использовать его для записи наших привязанных к диску и сети реализаций User в классе UserRepository :

Источник

Понравилась статья? Поделить с друзьями:
Добавить комментарий
  • Как сделать успешный бизнес на ритуальных услугах
  • Выездной кейтеринг в России
  • Риски бизнеса: без чего не обойтись на пути к успеху
  • android studio сохранение настроек приложения
  • android studio сохранение данных при закрытии приложения