- Основы создания интерфейса
- Введение в создание интерфейса
- Создание интерфейса в коде java
- Компоненты Android приложения
- Введение в компоненты архитектуры Android
- 1. Чего не хватало Android?
- Архитектура приложения
- Старые ошибки
- 2. Android-архитектура
- Новая рекомендуемая архитектура
- 3. Компоненты архитектуры
- Компоненты, связанные с жизненным циклом
- Компонент LiveData
- Компонент ViewModel
- Room компонент
- Добавление компонентов архитектуры в ваш проект
- Заключение
Основы создания интерфейса
Введение в создание интерфейса
Графический интерфейс пользователя представляет собой иерархию объектов android.view.View и android.view.ViewGroup . Каждый объект ViewGroup представляет контейнер, который содержит и упорядочивает дочерние объекты View . В частности, к контейнерам относят такие элементы, как RelativeLayout, LinearLayout, GridLayout, ConstraintLayout и ряд других.
Простые объекты View представляют собой элементы управления и прочие виджеты, например, кнопки, текстовые поля и т.д., через которые пользователь взаимодействует с программой:
Большинство визуальных элементов, наследующихся от класса View, такие как кнопки, текстовые поля и другие, располагаются в пакете android.widget
При определении визуального у нас есть три стратегии:
Создать элементы управления программно в коде java
Объявить элементы интерфейса в XML
Сочетание обоих способов — базовые элементы разметки определить в XML, а остальные добавлять во время выполнения
Сначала рассмотрим первую стратегию — определение интерейса в коде Java.
Создание интерфейса в коде java
Для работы с визуальными элементами создадим новый проект. В качестве шаблона проекта выберем Empty Activity :
Пусть он будет называться ViewsApp:
И после создания проекта два основных файла, которые будут нас интересовать при создании визуального интерфейса — это класс MainActivity и определение интерфейса для этой activity в файле activity_main.xml .
Определим в классе MainActivity простейший интерфейс:
При создании виджетов в коде Java применяется их конструктор, в который передается контекст данного виджета, а точнее объект android.content.Context , в качестве которого выступает текущий класс MainActivity.
Здесь весь интерфейс представлен элементом TextView, которое предназначено для выводa текста. С помощью методов, которые, как правило, начинаются на set , можно установить различные свойства TextView. Например, в данном случае метод setText() устанавливает текст в поле, а setTextSize() задает высоту шрифта.
Для установки элемента в качестве интерфейса приложения в коде Activity вызывается метод setContentView() , в который передается визуальный элемент.
Если мы запустим приложение, то получим следующий визуальный интерфейс:
Подобным образом мы можем создавать более сложные интерейсы. Например, TextView, вложенный в ConstraintLayout:
Для каждого контейнера конкретные действия по добавлению и позиционированию в нем элемента могут отличаться. В данном случае контейнеров выступает класс ConstraintLayout, поэтому для определения позиционирования и размеров элемента необходимо создать объект ConstraintLayout.LayoutParams . (Для LinearLayout это соответственно будет LinearLayout.LayoutParams, а для RelativeLayout — RelativeLayout.LayoutParams и т.д.). Этот объект инициализируется двумя параметрами: шириной и высотой. Для указания ширины и высоты можно использовать константу ViewGroup.LayoutParams.WRAP_CONTENT , которая устанавливает размеры элемента, необходимые для размещения а экране его содержимого.
Далее определяется позиционирование. В зависимости от типа контейнера набор устанавливаемых свойств может отличаться. Так, строка кода
указывает, что левая граница элемента будет выравниваться по левой ганице контейнера.
указывает, что верхняя граница элемента будет выравниваться по верхней ганице контейнера. В итоге элемент будет размещен в левом верхнем углу ConstraintLayout.
Для установки всех этих значений для конкретного элемента (TextView) в его метод setLayoutParams() передается объект ViewGroup.LayoutParams (или один из его наследников, например, ConstraintLayout.LayoutParams).
Все классы контейнеров, которые наследуются от android.view.ViewGroup (RelativeLayout, LinearLayout, GridLayout, ConstraintLayout и т.д.), имеют метод void addView(android.view.View child) , который позволяет добавить в контейнер другой элемент — обычный виджет типа TextView или другой контейнер. И в данном случае посредством данного метода TextView добавляется в ConstraintLayout:
Опять же отмечу, что для конкретного контейнера конкретные действия могут отличаться, но как правило для всех характерно три этапа:
Создание объекта ViewGroup.LayoutParams и установка его свойств
Передача объекта ViewGroup.LayoutParams в метод setLayoutParams() элемента
Передача элемента для добавления в метод addView() объекта контейнера
Хотя мы можем использовать подобный подход, в то же время более оптимально определять визуальный интерейс в файлах xml, а всю связанную логику определять в классе activity. Тем самым мы достигнем разграничения интерфейса и логики приложения, их легче будет разрабатывать и впоследствии модифицировать. И в следующей теме мы это рассмотрим.
Источник
Компоненты Android приложения
1. Операционная система Android
Android — операционная система, основанная на Linux с интерфейсом программирования Java. Это предоставляет нам такие инструменты, как компилятор, дебаггер и эмулятор устройства, а также его (Андроида) собственную виртуальную машину Java (Dalvik Virtual Machine — DVM). Android создан альянсом Open Handset Alliance, возглавляемым компанией Google.
Android использует специальную виртуальную машину, так званую Dalvik Virtual Machine. Dalvik использует свой, особенный байткод. Следовательно, Вы не можете запускать стандартный байткод Java на Android. Android предоставляет инструмент «dx», который позволяет конвертировать файлы Java Class в файлы «dex» (Dalvik Executable). Android-приложения пакуются в файлы .apk (Android Package) программой «aapt» (Android Asset Packaging Tool) Для упрощения разработки Google предоставляет Android Development Tools (ADT) для Eclipse. ADT выполняет автоматическое преобразование из файлов Java Class в файлы dex, и создает apk во время развертывания.
2. Основные компоненты Android
Android-приложения состоят из следующих частей:
- Activity/Деятельность (далее Активити) — представляет собой схему представления Android-приложений. Например, экран, который видит пользователь. Android-приложение может иметь несколько активити и может переключаться между ними во время выполнения приложения.
- Views/Виды — Пользовательский интерфейс активити, создаваемый виджетами классов, наследуемых от «android.view.View». Схема views управляется через «android.view.ViewGroups».
- Services/Службы — выполняет фоновые задачи без предоставления пользовательского интерфейса. Они могут уведомлять пользователя через систему уведомлений Android.
- Content Provider/Контент-провайдеры — предоставляет данные приложениям, с помощью контент-провайдера Ваше приложение может обмениваться данными с другими приложениями. Android содержит базу данных SQLite, которая может быть контент-провайдером
- Intents/Намерения (далее Интенты) — асинхронные сообщения, которые позволяют приложению запросить функции из других служб или активити. Приложение может делать прямые интенты службе или активити (явное намерение) или запросить у Android зарегистрированные службы и приложения для интента (неявное намерение). Для примера, приложение может запросить через интент контакт из приложения контактов (телефонной/записной книги) аппарата. Приложение регистрирует само себя в интентах через IntentFilter. Интенты — мощный концепт, позволяющий создавать слабосвязанные приложения.
- Broadcast Receiver/Широковещательный приемник (далее просто Приемник) — принимает системные сообщения и неявные интенты, может использоваться для реагирования на изменение состояния системы. Приложение может регистрироваться как приемник определенных событий и может быть запущено, если такое событие произойдет.
Другими частями Android являются виджеты, или живые папки (Live Folders), или живые обои (Live Wallpapers). Живые папки отображают источник любых данных на «рабочем столе» без запуска соответствующих приложений.
3. Безопасность и разрешения
Android определяет конкретные разрешения для определенных задач.
Android-приложения описываются файлом «AndroidManifest.xml». В этих файлах должны быть объявлены все активити, службы, приемники и контент-провайдеры приложения. Также он должен содержать требуемые приложением разрешения. Детальное описание полей смотри в здесь.
5. R.java, Resources и Assets
Каталог «gen» в Android-проекте содержит генерированные значения.
Тогда как каталог „res“ хранит структурированные значения, известные платформе Android, каталог „assets“ может быть использован для хранения любых данных. В Java Вы можете получить доступ к этим данным через AssetsManager и метод getAssets().
6. Активити и Макеты (layout)
Пользовательский интерфейс для деятельности (Activity) определяется с помощью макетов. Во время исполнения макеты — экземпляры «android.view.ViewGroups». Макет определяет элементы пользовательского интерфейса, их свойства и расположение. Элементы UI основываются на классе «android.view.View».
Макет может быть определен с помощью Java-кода или с помощью XML.
7. Активити и жизненный цикл
Операционная система контролирует жизненный цикл Вашего приложения.
Наиболее важные методы:
onSaveInstanceState() — вызывает, если активити остановлено. Используется для сохранения данных при восстановлении состояния активити, если активити возобновлено
onPause() — всегда вызывается, если активити завершилось, может быть использовано, для освобождения ресурсов или сохранения данных
onResume() — вызвано, если активити возобновлено, может быть использовано для инициализации полей
Источник
Введение в компоненты архитектуры Android
Android был представлен миру еще в 2005 году, и за эти 12 лет существования платформа достигла удивительного успеха, став самой установливаемой мобильной ОС. За это время было запущено 14 различных версий операционной системы, Android всегда становится более зрелой. Тем не менее, очень важная область платформы по-прежнему игнорировалась: стандартный шаблон архитектуры, способный обрабатывать особенности платформы и достаточно простой, чтобы его мог понять средний разработчик.
Ну, лучше поздно, чем никогда. В последнем Google I/O команда Android, наконец, решила эту проблему и ответила на призывы разработчиков по всему миру, объявив официальную рекомендацию для архитектуры приложений Android и предоставив ее для реализации: новая архитектурные компоненты. Что еще лучше так это то, что им удалось это сделать без ущерба для открытости системы, которую все мы знаем и любим.
В этом уроке мы рассмотрим стандартизованную архитектуру, предложенную командой Android в Google I/O, и рассмотрим основные элементы новых компонентов архитектуры: Lifecycle , ViewModel , LifeData и Room . Мы не будем уделять слишком много внимания коду, вместо этого фокусируясь на концепции и логике этих тем. Мы также рассмотрим некоторые простые фрагменты, все они написаны с использованием Kotlin, изумительного языка, который теперь официально поддерживается Android.
1. Чего не хватало Android?
Если вы только начинаете свое путешествие в качестве разработчика, возможно, вы точно не знаете, о чем я говорю. В конце концов, архитектура приложений может оказаться неясной темой. Но поверьте мне, вы скоро узнаете ее значение! По мере того как приложение растет и становится более сложным, его архитектура становится все более важной. Это может буквально превратить вашу работу в блаженство или же сделать ее настоящим адом.
Архитектура приложения
Примерно, архитектура приложения представляет собой последовательный план, который необходимо выполнить до начала процесса разработки. В этом плане представлена карта того, как различные компоненты приложения должны быть организованы и связаны друг с другом. В нем представлены руководящие принципы, которые следует соблюдать в процессе разработки и некоторые жертвы (как правило, связанные с большим количеством классов и шаблонов), которые в конечном итоге помогут вам создать хорошо написанное приложение, которое будет легче тестировать, расширять и поддерживать.
Архитектура прикладного программного обеспечения — это процесс определения структурированного решения, отвечающего всем техническим и эксплуатационным требованиям, при одновременной оптимизации общих атрибутов качества, таких как производительность, безопасность и управляемость. Она включает в себя ряд решений, основанных на широком спектре факторов, и каждое из этих решений может оказать значительное влияние на качество, производительность, поддерживаемость и общий успех приложения.
— Руководство по архитектуре и дизайну программного обеспечения Microsoft
Хорошая архитектура учитывает множество факторов, особенно характеристики и ограничения системы. Есть много разных архитектурных решений, все из них со своими плюсами и минусами. Однако некоторые ключевые понятия являются общими для всех видений.
Старые ошибки
До последнего Google I/O система Android не рекомендовала какую-либо конкретную архитектуру для разработки приложений. Это означает, что вы были совершенно свободны в принятии любой модели: MVP, MVC, MVPP или даже отсутствие какого либо шаблона вообще. Кроме того, инфраструктура Android даже не предоставляла собственные решения проблем, создаваемых самой системой, в частности жизненного цикла компонента.
Итак, если вы хотите использовать шаблон Model View Presenter для вашего приложения, вам нужно было придумать свое собственное решение с нуля, написать много шаблонов кода или взять библиотеку без официальной поддержки. И это отсутствие стандартов создало много плохо написанных приложений, с кодовыми базами, которые трудно поддерживать и тестировать.
Как я уже сказал, эта ситуация подвергалась критике годами. На самом деле, я недавно написал об этой проблеме и о том, как ее решить в разделе «Как использовать модель View Presenter для Android». Но важно то, что через 12 лет команда Android наконец решила выслушать наши жалобы и помочь нам в решении этой проблемы.
2. Android-архитектура
В новом руководстве по архитектуре Android определены некоторые ключевые принципы, которые должны соответствовать хорошему Android-приложению, а также оно предлагает безопасный путь для разработчика по созданию хорошего приложения. Однако в руководстве четко указано, что представленный маршрут не является обязательным, и в конечном итоге решение является личным; Разработчик должен решить, какой тип архитектуры он хочет принять.
Согласно руководству, хорошее приложение для Android должно обеспечить четкое разделение обязанностей и управлять пользовательским интерфейсом раздельно от модели. Любой код, который не обрабатывает взаимодействие с пользовательским интерфейсом или операционной системой, не должен находиться в Activity или Fragment, поскольку сохранение их как можно более чистыми позволит вам избежать многих проблем, связанных с жизненным циклом приложения. В конце концов, система может уничтожить действия или фрагменты в любое время. Кроме того, данные должны обрабатываться с помощью моделей, которые изолированы от пользовательского интерфейса и, следовательно, от проблем жизненного цикла.
Новая рекомендуемая архитектура
Архитектура, которую рекомендует Android, не может быть легко отмечена среди стандартных шаблонов, которые мы знаем. Она похожа на шаблон Model View Controller, но она настолько тесно связана с архитектурой системы, что трудно помечать каждый элемент, используя известные соглашения. Однако это не актуально, так как важно, чтобы архитектура основывалась на новых компонентах для создания разделения обязанностей, с хорошей способностью к тестированию и сопровождению. А еще лучше, ее легко реализовать.
Чтобы понять, что предлагает команда Android, мы должны знать все элементы компонентов архитектуры, так как именно они будут делать все тяжелую работу для нас. Есть четыре компонента, каждый из которых имеет определенную роль: Room , ViewModel, LiveData и Lifecycle . У всех этих частей есть свои обязанности, и они работают вместе, чтобы создать прочную архитектуру. Давайте рассмотрим упрощенную схему предлагаемой архитектуры, чтобы лучше понять ее.
Как вы можете видеть, у нас есть три основных элемента, каждый из которых имеет свою ответственность.
- Activity и фрагмент Fragment собой слой View , который не имеет дело с бизнес-логикой и сложными операциями. Он только настраивает представление, обрабатывает взаимодействие пользователя и, самое главное, наблюдает и демонстрирует элементы LiveData , взятые из ViewModel .
- ViewModel автоматически отслеживает состояние Lifecycle у представления, сохраняя согласованность во время изменений конфигурации и других событий жизненного цикла Android. Также требуется представление для извлечения данных из Repository , который предоставляется в качестве наблюдаемого LiveData . Важно понимать, что ViewModel никогда не ссылается на View напрямую и что обновления данных всегда выполняются объектом LiveData .
- Repository не является специальным компонентом Android. Это простой класс без какой-либо конкретной реализации, который отвечает за выборку данных из всех доступных источников, от базы данных до веб-служб. Он обрабатывает все эти данные, как правило, преобразуя их в наблюдаемые LiveData и делая их доступными для ViewModel .
- База данных Room — это библиотека SQLite, которая облегчает процесс работы с базой данных. Она автоматически записывает кучу готового кода, проверяет ошибки во время компиляции, и, самое главное, она может напрямую возвращать запросы с наблюдаемыми LiveData .
Я уверен, что вы заметили, что мы много говорили о наблюдателях. Шаблон Наблюдатель является одним из базовых для компонентов LiveData и Lifecycle . Этот шаблон позволяет объекту уведомлять список наблюдателей о любых изменениях в его состоянии или данных. Поэтому, когда Activity наблюдает объект LiveData , он будет получать обновления, когда эти данные подвергаются какой-либо модификации.
Еще одна рекомендация для Android состоит в том, чтобы консолидировать свою архитектуру, используя систему Injection Dependency, такую как Dagger 2 от Google, или используя шаблон Service Locator (который проще, чем DI, но без ряда его преимуществ). Мы не будем рассматривать DI или Service Locator в этом уроке, но у Envato Tuts + есть отличные уроки по этим темам. Однако имейте в виду, что есть некоторые особенности работы с Dagger 2 и компонентами Android, которые будут объяснены во второй части этой серии.
3. Компоненты архитектуры
Мы должны глубоко погрузиться в аспекты новых компонентов, чтобы иметь возможность реально понять и принять эту модель архитектуры. Тем не менее, в этом уроке мы не будем разбираться во всех деталях. Из-за сложности каждого элемента в этом уроке мы поговорим только об общей идее каждого из них и рассмотрим некоторые упрощенные фрагменты кода. Мы постараемся охватить достаточно, чтобы представить компоненты и начать работу. Но не бойтесь, потому что будущие статьи в этой серии будут погружаться уже глубоко и охватывать все особенности компонентов архитектуры.
Компоненты, связанные с жизненным циклом
У большинства компонентов приложения Android есть привязанные к ним жизненные циклы, которые управляются непосредственно самой системой. До недавнего времени разработчику приходилось следить за состоянием компонентов и действовать соответственно, инициализировать и заканчивать задачи в соответствующее время. Однако было очень легко запутаться и сделать ошибки, связанные с этим типом операции. Но пакет android.arch.lifecycle все это изменил.
Теперь к действиям и фрагментам привязан объект Lifecycle , который можно наблюдать с помощью классов LifecycleObserver , например ViewModel или любого объекта, реализующего этот интерфейс. Это означает, что наблюдатель получит обновления об изменениях состояния объекта, которые он наблюдает, например, когда действие приостановлено или когда оно запущено. Он также может проверять текущее состояние наблюдаемого объекта. Поэтому теперь гораздо проще обрабатывать операции, которые должны учитывать жизненные циклы фреймворка.
На данный момент для создания Activity или Fragment , который соответствует этому новому стандарту, вы должны унаследовать от LifecycleActivity или LifecycleFragment . Однако вполне возможно, что это не всегда будет необходимо, так как команда Android стремится полностью интегрировать эти новые инструменты со своей структурой.
LifecycleObserver получает события Lifecycle и может реагировать через аннотацию. Не требуется переопределение метода.
Компонент LiveData
Компонент LiveData является держателем данных, который содержит значение, которое можно наблюдаться. Учитывая, что наблюдатель предоставил Lifecycle во время создания LiveData , LiveData будет вести себя в соответствии с состоянием Lifecycle . Если состояние Lifecycle наблюдателя STARTED или RESUMED , наблюдатель active ; В противном случае он inactive .
LiveData знает, когда данные были изменены, а также когда наблюдатель active и должен получать обновление. Еще одна интересная характеристика LiveData заключается в том, что она способна удалять наблюдателя, если он находится в состоянии Lifecycle.State.DESTROYED , избегая утечек памяти при наблюдении за действиями и фрагментами.
LiveData должен реализовывать методы onActive и onInactive .
Чтобы наблюдать компонент LiveData , вы должны вызвать observer(LifecycleOwner, Observer ) .
Компонент ViewModel
Одним из наиболее важных классов новых компонентов архитектуры является ViewModel , который предназначен для хранения данных, связанных с пользовательским интерфейсом, сохраняя свою целостность во время изменений конфигурации, таких как вращения экрана. ViewModel может общаться с Repository , получая LiveData от него и делая его доступным, в свою очередь, для наблюдения из отображения. ViewModel также не потребуется создавать новые вызовы в Repostitory после изменений конфигурации, что значительно оптимизирует код.
Чтобы создать модель представления, отнаследуйтесь от класса ViewModel .
Чтобы получить доступ из представления, вы можете вызвать ViewProviders.of(Activity | Fragment).get (ViewModel::class) . Этот фабричный метод вернет новый экземпляр ViewModel или при необходимости сохранит его.
Room компонент
Android с самого начала поддерживает SQLite; Однако, чтобы заставить его работать, всегда приходилось писать много начального кода. Кроме того, SQLite не сохранял POJO (простые старые объекты Java) и не выполнял запросы во время компиляции. Room пришел чтобы решить эти проблемы! Это библиотека сопоставления SQLite, способная сохранять Java POJO, напрямую конвертировать запросы в объекты, проверять ошибки во время компиляции и получать данные LiveData из результатов запроса. Room представляет собой библиотеку реляционных объектов с некоторыми классными дополнениями для Android.
До сих пор вы могли бы сделать большую часть того, что может Room , используя другие ORM библиотеки Android. Однако ни одна из них официально не поддерживается и, самое главное, они не могут возвращать результаты в виде LifeData . Библиотека Room идеально подходит как слой хранения данных предлагаемой архитектуры Android.
Чтобы создать базу данных Room , вам понадобится @Entity , которая может быть любым Java POJO, интерфейс @Dao для создания запросов и операций ввода-вывода, а также абстрактный классом @Database , который должен расширять RoomDatabase .
Добавление компонентов архитектуры в ваш проект
На данный момент для использования новых компонентов архитектуры вам необходимо сначала добавить репозиторий Google в файл build.gradle . Для получения дополнительной информации см. Официальное руководство.
Заключение
Как вы можете видеть, стандартизованная архитектура, предлагаемая Android, включает в себя множество концепций. Не ожидайте сразу полного понимания этой темы. В конце концов, мы просто представляем тему. Но у вас наверняка уже достаточно знаний, чтобы понять логику архитектуры и роли различных ее компонентов.
Мы говорили о большинстве тем, связанных с предлагаемой архитектурой Android и ее компонентами; Однако эта первая часть не может быть описана в деталях о некоторых дополнительных функциях, таких как класс Repository и система Dagger 2 . Мы рассмотрим эти темы в следующих статьях.
Источник