- Архитектура Android-приложений. Часть III — основные части приложения
- Android Application Class
- Android Activity Lifecycle
- Android activity lifecycle is first thing to be known as android developer. Here I’m sharing with you some facts and…
- Android. Собеседование #3. Основные классы приложения
- 1. Что такое Context?
- 2. Для чего используется Intent?
- 3. Что такое Bundle?
- 4. Расскажите про класс Application?
Архитектура Android-приложений. Часть III — основные части приложения
Итак, мы уже говорили о происхождении архитектуры ОС Android и о шаблонах, реализованных в этой архитектуре. Теперь настала пора поговорить о том, из чего состоит Android-приложение.
В этой статье будут представлены основные «персонажи» архитектуры Android-приложения.
В общем случае, Android-приложение состоит из:
- Java-классов, являющихся подклассами основных классов из Android SDK (View, Activity, ContentProvider, Service, BroadcastReciever, Intent) и Java-классов, у которых нет родителей в Android SDK.
- Манифеста приложения
- Ресурсов наподобие строк, изображений и т.п.
- Файлов
Java классы
На следующей диаграмме представлена иерархия основных классов из Android SDK, с которыми предстоит иметь дело разработчику:
На самом деле классов намного больше, но это основные. Выделенные жёлтым — те, с которыми разработчик работает непосредственно (в частности, наследуются от них). Остальные так же важны, но они реже используются напрямую.
View — базовый класс для всех виджетов пользовательского интерфейса (GUI widgets). Интерфейс Android-приложения представляет собой дерево экземпляров наследников этого класса. Можно создать это дерево программно, но это неправильно. Пользовательский интерфейс определяется с помощью XML (файлы слоёв, layout files), а во время исполнения автоматически превращается (inflate, термин Android) в дерево соответствующих объектов.
Класс Activity и его подклассы содержат логику, лежащую за пользовательским интерфейсом. При ближайшем рассмотрении этот класс соответствует ViewModel в архитектурном шаблоне Model-View-ViewModel (MVVM). Отношение между подклассом Activity и пользовательским интерфейсом — это отношение один к одному; обычно каждый подкласс Activity имеет только один связанный с ним слой пользовательского интерфейса, и наоборот. Activity имеет жизненный цикл.
В течении жизненного цикла Activity может находиться в одном из трёх состояний:
- Активно и выполняется — этот пользовательский интерфейс находится на переднем плане (говоря технически — на вершине стека активити)
- Приостановлено — если данный интерфейс пользователя потерял фокус, но всё ещё видим. В таком состоянии никакой код не выполняется.
- Завершено — если интерфейс пользователя невидим. В таком состоянии код не выполняется.
Код активити выполняется только когда соответствующий интерфейс пользователя видим и имеет фокус. Нет гарантии, что объект Activity и связанные с ним объекты находятся в памяти, когда активити приостановлено или завершено (очень важно помнить об этом; ранее мы уже обсуждали этот момент управления памятью в Android).
Класс ContentProvider и его подклассы представляют model в архитектуре MVVM. В большинстве практических случаев это обёртка над базой данных SQLite с немного причудливым способом доступа на основе URI. Теоретически, никто не мешает разработчику создать ContentProvider на основе чего-то ещё, кроме базы данных. Тем не менее, существующий метод query() контент-провайдера возвращает объект Cursor, который крайне похож на JDBC ResultSet интерфейсом и тем, как он работает. Поэтому вряд ли кто-то усомнится, что настоящее назначение контент-провайдеров — инкапсулировать базу данных.
Я не знаю, как комманда Android пришла к такому дизайну, но, по-моему, здесь соединены две хороших, но не слишком совместимых идеи.
И вот почему я так считаю. Основная идея контент-провайдеров, похоже, базируется на архитектуре AJAX приложений. AJAX приложения обычно используют архитектуру MVVM, где модель представлена как URI на стороне сервера (тем не менее, это изменилось с поялвинем HTML5, который позволяет хранить данные локально). В самом деле, тот факт, что контент-провайдеры запрашиваются с помощью URI и создают расширение с помощью типов MIME указывает на то, что в основе лежит AJAX. Напомню, ребята из Google создали большое количество AJAX приложений, таких как Gmail, Google Docs и т.п., поэтому вполне естественно, что идеи заимствовались из архитектуры AJAX.
Возможно, кто-то ещё пришёл с ещё одной отличной идеей: как было бы здорово иметь полноценную реляционную базу на мобильном устройстве! (замечу, это было примерно в 2005 году, когда мобильные телефоны были намного слабее, чем сейчас). И, как результат, они соединили две хороших идеи в один класс ContentProvider. Как это обычно и случается в разработке ПО, соединение двух хороших идей не всегда даёт в результате хорошую идею; в случае Android мы имеем несколько обескураживающий дизайн контент-провайдеров.
Класс Service и его подклассы я затрудняюсь как-то классифицировать. Я думаю, ребята из Google испытывают те же трудности (прочтите, пожалуйста, их документацию). Их классификация, в основном, говорит, чем этот класс не является. Я лично думаю, что сервис — это разновидность Model, обслуживающая несколько иные варианты использования, нежели ContentProvider.
По-моему, архитектурный дизайн Android Service навеян сервисами OSGI.
Думаю, сервисы были созданы ребятами из Google как решение логической проблемы, возникшей из-за модели потоков Android.
Подумайте над этим: Activity активно и выполняется только когда его пользовательский интерфейс находится на переднем плане. Как только интерфейс другого Activity закрывает собой текущее, последнее останавливается, даже если оно что-то делало. А что, если вам нужно выполнять некую операцию, даже если процесс, которые её выполняет, не на переднем плане? С помощью Activity вы не сможете этого сделать. Вы не сможете это сделать и с помощью ContentProvider, поскольку у них нет собственного жизненного цикла, и они могут выполняться только пока Activity, использующее его, активно.
И тут на помощь приходят сервисы. Они могут выполняться даже когда процесс, в котором они работают, не на переднем плане. Так, если вы разрабатываете активити, выполняющее растянутую во времени операцию, которая должна завершиться даже работая в фоне, вы должны создать Service, реализующий эту операцию, и запустить его из Activity.
Service так же имеет жизненный цикл. Это означает, что он может быть инстанцирован и запущен Android-приложением по некому условию (мы обсудим это позже).
Как я уже упоминал, Service, как model, приследует более общие цели, нежели ContentProvier. Он может использовать базу данных, но его API не связано с БД, как в случае ContentProvider. В большинстве случаев сервисы используются для связи с внешними серверами.
Класс BroadcastReceiver и его подклассы представляют собой «подписчика» в механизме взаимодейтсвия издатель/подписчик, реализованном в архитектуре Android.
Мы уже говорили о механизмах взаимодействия в предыдущей статье.
Конечно, разработчик под Android не ограничен одним только расширением классов из Android SDK. Он может писать собственные классы так, как захочет. Но все они будут только хелперами («helper classes») для классов из Andoird SDK.
Манифест Android
Манифест Android — ещё одна важная часть Android-приложения. Идея была навеяна манифестами плагинов для Eclipse.
Манифест Android представляет собой XML файл и выполняет несколько функций. Вот как их описывает Google:
- Определяет имя Java-пакета приложения. Имя пакета представляет собой уникальный идентификатор для приложения.
- Описывает компоненты приложения — активити, сервисы, броадкаст-ресиверы и контент-провайдеры. Определяет имена классов, реализующие каждый из компонентов и оглашает их возможности (например, какие Intent-сообщения они могут обрабатывать). Эти объявления позволяют системе Android знать, какие компоненты и при каких условиях могут быть запущены.
- Предопределяет процессы, которые будут содержать компоненты приложения.
- Объявляет разрешения, которые приложение должно иметь для доступа к защищённым частям API и взаимодействия с другими приложениями.
- Также объявляет разрешения, которые требуются для доступа к компонентам приложения.
- Перечисляет классы Instrumentation, которые предоставляют профайлинг и другую информацию во время работы приложения. Эти объявления присутствуют в манифесте только пока приложение разрабатывается и тестируется; они удаляются перед публикацией приложения.
- Объявляет минимальный уровень Android API, который требует приложение.
- Перечисляет библиотеки, с которыми приложение должно быть связано.
Обратите внимание на второй пункт. Имеется ввиду, что если некий класс расширяет Activity, ContentProvider, BroadcastReceiver или Service в вашем приложении, этот класс не может быть использован до тех пор, пока он не описан в манифесте.
Ресурсы
Каждое современное GUI приложение в той или иной форме использует ресурсы. Android-приложения — не исключение. Они используют следующие типы ресурсов:
- Изображения
- Слои GUI (XML файлы)
- Объявления меню (XML файлы)
- Текстовые строки
Способ, которым ресурсы связываются с Android-приложением — это что-то необычное. Как правило, в Java ресурсы идентифицируются строками. Такие строки могут содержать, например, путь и имя файла, содержащего изображение, или ID данной строки и т.п. Проблема в том, что ошибки в таких ссылках не могут быть обнаружены в процессе трансляции кода.
Давайте рассмотрим следующий пример. Файл с именем mybutton.png содержит картинку для кнопки. Разработчик совершает ошибку и набирает mybuton.png, ссылаясь на ресурс из кода. Как итог, код пытается использовать несуществующий ресурс, но компиляция пройдёт успешно. Ошибка может быть обнаружена только в ходе тестирования (а может и не быть обнаружена вовсе).
Ребята из Google нашли элегантное решение этой проблемы. При сборке Android-приложения генерируется специальный Java-класс с именем R (всего лишь одна буква). Этот класс содержит несколько static final наборов данных. Каждый такой набор данных — ссылка на отдельный ресурс. Эти ссылки используются в коде приложения для связи с ресурсами. Теперь каждая ошибка в ссылке на ресурсы проявляет себя в процессе компиляции.
Файлы
Android-приложение использует несколько разных типов файлов:
- Файлы «общего назначения»
- Файлы БД
- Файлы Opaque Binary Blob (OBB) (они представляют собой зашифрованную файловую систему, которая может быть монтирована для приложения)
- Закешированные файлы
Хотя, в конечно итоге, все они только файлы Linux, имеет смылсл рассматривать их как отдельные типы файлов только в разрезе обработки их различным API и отдельного хранения. Также они отделены от файлов, хранящихся во внутреннем или внешнем хранилище (последнее может отсутствовать или исчезнуть/появиться в любой момент).
API для работы с файлами реализован классом Context, от которого порождены классы Activity и Service. Этот класс уже обсуждался нами здесь.
На сегодня это всё. В следующей статье мы поговорим о том, как различные части Android-приложения взаимодействуют между собой.
Источник
Android Application Class
W hile Starting App development, we tend to miss out simple basic stuffs either by ignorance or by curiosity to build million dollar app. But, Hey! Why so serious !. Building a App is bit of Art ,bit of Engineering and frequently both.
Activity Life Cycle is stages of activity in run time, knowing these would save you from headaches while you dive deeper in development.
I have written a post that will help you to understand activity lifecycle in a practical approach. Check it out
Android Activity Lifecycle
Android activity lifecycle is first thing to be known as android developer. Here I’m sharing with you some facts and…
Application class is a base class of Android app containing components like Activities and Services. Application or its sub classes are instantiated before all the activities or any other application objects have been created in Android app.
You Don’t have to import or extend application class, they are predefined. We cannot change application class but we could give additional instruction to it by extending it. Refer here for more info.
Create a java class named SubApplication and Application as Superclass
By extending Application class you could get boilerplate code like this
Check in AndroidManifest.xml and set Application name to SubApplication that you created
Lets take a situation where we should know which activity is currently running and we have to use register network receiver in all our activities. To this we used to write same code in all the activities or write a base class and extend that class instead of extending AppCompactActivity.
We have Activity Life cycle in one hand and Application class in another, what sense they make? Well actually they do? Let’s look into it.
- In application class create static Activity variable it is accessible from whole project.
2. Register Activity Life Cycle callback in onCreate method in application class. By this step we can get currently running activity in our app from mActivity.
3.Moving on to next, Create a Broadcast Receiver and write a method to check the internet connection. you can get the code here .
4. Register your broadcast receiver in Manifest File
But for SDK Above Nougat we need to register receiver and unregister in every activity we use programmatically or We can just register and unregister Commonly in Application class.
5. Create a Object for Broadcast Receiver in application class and Register it in onResume method and Unregister in onPause method.
Bit confused! Don’t Worry, Here is the Link to the files.
Thanks for reading out the article. Let me know if I have missed out something interesting so that I can be added. Be sure to clap/recommend as much as you can and also share with your friends.
Источник
Android. Собеседование #3. Основные классы приложения
1. Что такое Context?
Context представляет собой абстрактный класс в Android, от которого наследуются важные классы Application, Activity, Service. Важно отметить, что Fragment не наследуется от Context.
Класс Context предоставляет следующие возможности:
– получить доступ к различным ресурсам приложения, например к строковым ресурсам методом getString() или к графическим ресурсам getDrawable()
– запускать Activity
– отправлять широковещательное сообщения (broadcast) и регистрировать приёмники широковещательных сообщений (BroadcastReceiver)
– запускать/останавливать сервисы, а также биндить их к Activity
– получать пути к директориям приложения в памяти системы Android, например методом getFilesDir().
Чтобы получить объект класса Context, мы можем использовать следующие способы:
– внутри вложенного класса или метода получить ссылку на объект MainActivity – Activity.this
– внутри фрагмента получить ссылку на объект родительской активности – getActivity
– получить ссылку на базовый контекст – getBaseContext
– получить ссылку на объект приложения – getApplicationContext
– внутри активности или сервиса получить ссылку на этот объект – getContext
– this (то же, что и getContext)
В таблице ниже представлены возможности Context относительно различных компонентов приложения.
Возможности | Application | Service | Content Provider | Broadcast Receiver | Activity |
Отобразить Dialog, Toast | — | — | — | — | + |
Запустить Activity | — | — | — | — | + |
Использование Layout Inflation | — | — | — | — | + |
Запустить Service | + | + | + | + | + |
Привязать Service | + | + | + | — | + |
Отправить Broadcast | + | + | + | + | + |
Зарегестрировать BroadcastReceiver | + | + | + | — | + |
Доступ к resources | + | + | + | + | + |
Это не все возможности класса Context, рекомендую изучить его непосредственно в Android Studio.
2. Для чего используется Intent?
Intent – это класс в Android, который используется для для следующих возможностей:
– запуск Activity, передав объект Intent методу startActivity класса Context
– запуск сервиса, передав объект Intent методу startService класса Context
– отправка широковещательных сообщений, передав объект Intent методу sendBroadcast класса Context
Intent делится на два типа – явный (explicit) и неявный (Implicit). Явный объект Intent используется для запуска какого-либо конкретного компонента своего приложения, например.
Неявный объект Intent содержит в себе действие (Action), которое другому приложению необходимо выполнить, если оно это делать умеет, например отобразить карту или открыть PDF файл.
3. Что такое Bundle?
Bundle это потокобезопасный класс, который предназначен для хранения пар ключ-значение, т.е. мы можем положить в объект Bundle данные в виде примитивов либо объектов, реализующих интерфейс Parcelable. Может использоваться для передачи данных между Activity, для сохранения/восстановления данных при смены состояния Activity.
4. Расскажите про класс Application?
Application – класс в Android который позволяет отслеживать состояние приложения в целом. При создании процесса Android приложения (запуске приложения через launcher), в первую очередь всегда инициализируется класс Application и далее все остальные необходимые части приложения.
В классе есть интерфейс ActivityLifecycleCallbacks, содержащий все методы жизненного цикла Activity, которые вызываются после вызова методов в Activity приложения.
Также класс содержит такие методы, как onLowMemory() и onTrimMemory() по отслеживанию использования памяти приложением.
Context ресурсоёмкий класс, но его можно использовать в классе Application в качестве Singleton, потому как Application повторяет жизненный цикл самого приложения и статический Context будет создаваться и умирать вместе с ним. Это не будет вызывать утечек памяти и такой подход весьма удобно использовать для работы приложения.
Источник