Каких компонентов не существует в android приложении
- Определяет пользовательские разрешения которые необходимы приложению, такие как доступ в Интернет или чтение контактов.
- Объявление минимального API уровня (версии Android), необходимого для приложения.
- Объявление аппаратных и программных требований, такие как камера, Bluetooth, или мультитач экран.
- API библиотек с которые необходимы приложению, например библиотеки Google Maps.
- и много чего еще
В элементе <application> атрибут Android:icon указывает на ресурсы для иконки приложения.
В элементе <activity> атрибут Android:name определяет полный путь на имя класса Activity (деятельности), а атрибут Android:label задаёт заголовок приложения.
Система определяет компоненты, которые могут реагировать на намерение путём сравнения полученного Intent (намерения) от приложеия, с Intent filters (фильтр намерений), определённых в файлах манифеста других приложений.
При объявлении компонента в файле манифеста, можно дополнительно включить фильтр намерений, которые заявляют возможности компонента, чтобы он мог реагировать на запросы из других приложений. Для объявления фильтра намерения используется элемент <intent-filter>.
Activity (деятельность) в стороннем приложении создаёт Intent (намерение) с типом действия "send" (ACTION_SEND), которое система сопоставит с приложением электронной почты и запустит нужную Activity (деятельность).
Объявление требований приложений
Существует большое количество устройств, работающий под управлением системы Android, однако, не все они обеспечивают одинаковые функции и возможности. Чтобы не позволить установить приложение на устройство, в котором отсутствуют необходимые функции, необходимо объявить аппаратные и программные требования в файле манифеста. Большинство из этих заявлений существуют исключительно для ознакомления и система не читает их, однако внешние сервисы, таких как Google Play используют их, чтобы обеспечить фильтрацию для пользователей, которые ищут приложения для своего устройства.
Например, если приложение требует камеру и использует API, введённые в Android версии 2.1 (API уровень 7), надо записать эти требования в файл манифеста. Например так:
Таким образом, устройства, которые не имеют камеру или с версией Android ниже, чем 2.1 не смогут установить приложение из Google Play.
Однако, приложение может использовать камеру, но но это требование не является критичным для его работы. В этом случае приложение должно выполнять проверку во время выполнения, чтобы отключить функции, использующие камеру.
Ресурсы приложения
Приложения Android состоят не только из исходного кода, но также из ресурсов для визуального представления, такие как изображения или звуковые файлы. Для приложения необходимо определить меню, стили, цвета и разметку пользовательского интерфейса в файлах XML. Использование ресурсов даёт возможность изменять некоторые части приложения без модификации исходного кода, а также позволяет оптимизировать приложение для различных устройств (с различным языком интерфейса или размером экрана).
Для каждого ресурса, включённого в проект Android, SDK определяет уникальный идентификатор (целое число) в файле R.java, которое можно использовать для ссылки на ресурс из кода или из других ресурсов определённых в XML. Например, если приложение содержит изображение с именем logo.jpg (сохранённое в директории res/drawable), SDK сгенерирует идентификатор ресурса R.drawable.logo, которое можно использовать для ссылки на изображение.
Главным достоинством отдельного хранения исходного кода и ресурсов является возможность создать разные ресурсы для разных аппаратных конфигураций. Например, строки интерфейса для разных языков можно определять в различных xml файлах (они хранятся например в директории res/values-fr/ для французского языка). В зависимости от выбранного пользователем языка система Android подставляет нужные строки в интерфейс.
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-приложения состоят из следующих частей:
Другими частями 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 -приложениям.
Тем не менее, главным параметром Android -приложения является возможность использовать компоненты других приложений, если они дают на это соответствующие права . Допустим, нам нужен некий компонент с прокруткой для отображения текста, и похожий компонент уже реализован в другом приложении. Тогда у нас есть возможность использовать реализованный компонент . В этом случае наше приложение не копирует необходимый код к себе и не создает ссылку на него. Вместо этого приложение делает запрос на исполнение части кода другого приложения, где есть нужный нам компонент .
В Android существует четыре типа компонентов: Activities , Services , Broadcast receivers и Content providers .
1.6.1. Activities
Приложение может состоять из одного Activity или из нескольких. Это зависит от типа приложения и его дизайна. Одно Activity может вызвать другое. Каждое Activity задает окно для отображения, которое, обычно, занимает весь экран, но может быть меньше и плавать поверх других окон. Activity может использовать дополнительные окна, например, всплывающий диалог, который требует промежуточного ответа пользователя, или окно, которое отображает пользователям важную информацию при выборе элемента, заслуживающего особого внимания.
Визуальный интерфейс строится на основе иерархии визуальных компонентов, производных от базового класса View. Android имеет ряд готовых к использованию компонентов, а также кнопки, текстовые поля, полосы прокрутки, меню, флажки и многие другие.
Activity может находиться в одном из трех состояний:
- Active или Running – находится на переднем плане и имеет фокус для взаимодействия с пользователем.
- Paused – потеряло фокус, но все еще видно пользователю. Сверху находится другое Activity , которое или прозрачно или закрывает не весь экран. Приостановленное Activity полностью "живое" (его состояние сохранено), но может быть уничтожено системой в случае нехватки памяти.
- Stopped – полностью перекрыто другим Activity . Оно больше не видно пользователю и будет уничтожено системой, когда понадобится память.
Если Activity приостановлено или остановлено, система может удалить его из памяти, либо послать запрос на его завершение, или просто уничтожить его процесс. Когда Activity снова отображается пользователю, его состояние полностью восстанавливается.
Переходя от состояния к состоянию, Activity уведомляет об этом, вызывая следующие методы:
- void onCreate()
- void onStart()
- void onRestart()
- void onResume()
- void onPause()
- void onStop()
- void onDestroy()
Жизненный цикл Activity состоит из трех вложенных циклов (Рис. 1.3):
- Жизненный цикл activity начинается с вызова метода onCreate() , в котором производится первоначальная настройка глобального состояния, и завершается вызовом метода onDestroy() , в котором оно освобождает занятые ресурсы.
- Видимая часть жизненного цикла происходит между вызовами onStart() и onStop() . В течение этого времени пользователь может видеть Activity на экране, хотя оно может быть не на переднем плане и не взаимодействовать с пользователем. Методы onStart() и onStop() могут вызываться столько раз, сколько Activity становится видимым или скрытым для пользователя.
- На переднем плане Activity находится между вызовами onResume() и onPause() . В течение этого времени Activity находится поверх других и взаимодействует с пользователем. Activity может часто переходить в состояние паузы и выходить из него. Например, метод onPause() может быть вызван, когда устройство переходит в спящий режим или когда запускается другое Activity , а метод onResume() – при получении результата от закрывающегося Activity .
Следующая таблица более детально описывает каждый из уже перечисленных методов и его место в жизненном цикле Activity .
За ним всегда следует вызов метода onStart() .
За ним всегда следует вызов onResume()
За ним следует вызов onResume() , если Activity переходит на передний план, или onStop() , если оно скрывается.
За ним следует вызов onPause() .
За ним может быть вызван метод onResume() если Activity возвращается на передний план, или метод onStop() , если оно становится невидимым для пользователя.
Затем может быть вызван либо метод onRestart() , если Activity возвращается для взаимодействия с пользователем, либо метод onDestroy() , если оно завершается.
Обратите внимание на колонку "Может ли быть уничтожен?". Она указывает на то, может ли система уничтожить процесс, в котором запущено Activity , в любой момент после возврата из этого метода, не выполняя больше ни одной строчки кода Activity . Три метода: OnPause(), OnStop() и OnDestroy() – отмечены "Да". Но только метод OnPause() будет гарантированно вызван перед уничтожением процесса, поскольку он первый в этом списке, а OnStop() и OnDestroy() могут не вызываться. Поэтому для сохранения измененных данных нужно использовать метод OnPause() . Методы, отмеченные "Нет", защищают процесс, в котором запущено Activity, от уничтожения с момента их вызова.1.6.2. Типы процессов в Android-приложении
Жизненный цикл приложения тесно связан с жизненным циклом его процесса. Также он зависит от текущего состояния системы. В случае нехватки памяти, Android убивает наименее значимые процессы. Значимость процесса зависит от его типа. Типы процессов, в зависимости от важности, выглядят следующим образом (от наиболее до наименее важных):
- Процесс переднего плана – процесс приложения, с которым пользователь взаимодействует в данный момент. Процесс считается таковым, если его Activity находится на вершине Activity-стека (была вызвана функция onResume() , или его Broadcast Receiver работает в настоящее время (в данный момент исполняется приложением onReceive()) , или же его Service выполняет callback-методы, такие как onCreate() , onStart() или onDestroy() . Как правило, таких процессов очень мало и они закрываются в самую последнюю очередь.
- Видимый процесс — процесс, который имеет Activity, видимый конечному пользователю в данный момент времени. Процессов, которые выводятся на экран, очень мало, поэтому их работа прерывается только в крайнем случае, если не хватает ресурсов для активных приложений.
- Служебный процесс – процесс, содержащий Service, для которого была вызвана функция startService() , при условии, что данный Service сейчас работает.
- Процесс заднего фона. Данный процесс не имеет видимых пользователю Activity (была вызвана функция onStop()) . Как правило, существует множество фоновых процессов, работа которых завершается по принципу "последний запущенный закрывается последним", чтобы освободить ресурсы для приложений, работающих на переднем плане.
1.6.3. Services
Service – это некий процесс, который запускается в фоновом режиме. Как пример, Service может получать данные по сети, выполнять какие-либо длительные вычисления. Хорошим примером Service служит проигрыватель музыки. Пользователь может выбрать любую песню в проигрывателе, включить ее и закрыть плеер занявшись чем-нибудь другим. Музыка будет проигрываться в фоновом процессе. Service проигрывания музыки будет работать, даже если Activity плеера закрыта.
Подобно Activity, Service имеет свои методы жизненного цикла:
- void onCreate()
- void onStart(Intent intent)
- void onDestroy()
В полном жизненном цикле Service существует два вложенных цикла:
- полная целая жизнь Service – промежуток между временем вызова метода onCreate() и временем возвращения onDestroy() . Подобно Activity , для Services производят начальную инициализацию в onCreate() и освобождают все остающиеся ресурсы в onDestroy() ;
- активная целая жизнь Service – начинается с вызова метода onStart() . Этому методу передается объект Intent, который передавался в startService() .
Как и Activities, Services запускаются в главном потоке процесса приложения. По этой причине их следует запускать в отдельном потоке, чтобы они не блокировали другие компоненты или пользовательский интерфейс.
1.6.4. Broadcast receivers
Когда программа возвращается из onReceive() , приемник становится неактивным и система полагает, что работа объекта Broadcast receiver закончена. Процесс с активным широковещательным получателем защищен от уничтожения системой. Однако процесс, содержащий неактивные компоненты, может быть уничтожен системой в любое время, когда память, которую он потребляет, будет необходима другим процессам.
1.6.5. Content providers
Content providers предоставляют доступ к данным (чтение, добавление, обновление). Content provider может предоставлять доступ к данным не только своему приложению, но и другим. Данные могут размещаться в файловой системе, в базе данных.
В этой статье пойдет речь о том, как рассказать человеку, ранее не знакомому с программированием под Android, об основных его компонентах. Заинтересовать и показать, что все не так сложно, как многие думают. При этом сделать это за 15 минут и не уходя в объяснение какой-то базовой теории, которую каждый может прочитать сам и вернуться уже с уточняющими вопросами.
Когда я попробовал сделать это первый раз, был неприятно удивлен собой. Мое "простое и понятное" объяснение превратилось в занудство, в рамках которого четко прослеживалась отчаянная попытка объять необъятное и рассказать в двух словах обо всем понемногу. Нужно ли говорить, что такой рассказ скорее не заинтересует, а напугает Вашего собеседника, попутно уменьшив желание сделать что-то свое, даже если раньше в планах был небольшой калькулятор.
Не секрет, что в Интернете размещено огромное количество статей на эту тему, но в моем случае повествование будет немного отличаться: здесь будет только наглядная практика, без определений и прочих деталей. То есть смотрим — видим — комментируем происходящее. Смотрится, на мой взгляд, все достаточно просто и наглядно, куски кода получились тоже небольшие и очень простые, готовые к быстрому использованию в собственном проекте. Мне кажется, такой подход дает достаточно широкую обзорную картину классических инструментов Android, и при написании первого приложения вместо вопросов "что мне использовать" будут более конкретные вопросы "как именно мне использовать компонент Х". А уже все подробности об этом человек сможет узнать сам — если захочет.
Устанавливаем приложение, запускаем его, и… пока достаточно того, что перед нами открылось MainActivity. На вопрос "почему именно оно" ответ будет дан позднее.
Первым делом рассмотрим, откуда оно берется — из main_activity.xml, где объявлены все элементы интерфейса. Размещены они в LinearLayout, поэтому вопросы здесь вряд ли возникнут.
Простые компоненты
Toast
Теперь перейдем в MainActivity.java и первой кнопке его интерфейса — "Показать Toast" (всплывающее уведомление).
Находим идентификатор кнопки в main_activity.xml и переходим к ее OnClickListener в MainActivity.java.
Оказывается, чтобы вывести всплывающее уведомление, достаточно одной строки кода! Здорово, не правда ли?
Взаимодействие с другим Activity
Первая Activity
Вторая Activity
Теперь попробуем перейти куда-нибудь за пределы главной страницы приложения. Например, на другую такую страницу! Переходим во "Взаимодействие с другим Activity" — и мы попадаем в другую активность с другими элементами управления. Как разные активности в одном приложении передают данные между собой? Здесь самое время рассказать про два различных механизма: постоянное хранилище значений — shared_prefs, а также startActivityForResult / onActivityResult (не хотелось вставлять такое в начало, но все-таки кратко: если из открытой активности запустить новую активность при помощи startActivityForResult, то по завершении второй активности будет вызван onActivityResult в первой активности. Не пугайтесь, если это пока не понятно).
И, конечно же, продемонстрировать на практике!
Вопросы по основным элементам, из которых состоит приложение на Android.
1. Назовите основные компоненты Android приложение
2. Что такое Activity?
3. Опишите жизненный цикл Activity
При повороте экрана система полностью пересоздаёт экземпляр Activity. Для того, что сохранить какие-либо пользовательские данные и затем восстановить их в нашей Activity, используются следующие методы:
Стоит заметить, что Bundle с сохранёнными данными мы также получаем в методе onCreate(), но данную ситуацию нужно отдельно обрабатывать, чтобы не получить NullPointerException.
4. Что такое Service?
Service (служба) — это компонент android-приложения без видимого интерфейса, который работает в фоновом режиме. Служба обязательно должна быть объявлена в файле AndroidManifest в теге application:
Service запускается в главном потоке приложения, поэтому если необходимо обработать в нём какую либо тяжёлую логику, необходимо создавать в нём новый поток.
Дополнительные ответы по Android Services читайте тут.
5. Опишите Broadcast receiver?
Либо зарегистрировать его в манифесте при помощи тега <intent-filter>.
BroadcastReceiver можно динамически зарегистрировать с помощью метода registerReceiver(), или статически создать его в тэге <receiver> в файле AndroidManifest приложения. Запускается в главном потоке приложения.
6. Способ применения ContentProvider?
Поставщик содержимого представляет собой оболочку над базой данных приложения. Если наше приложение использует базу данных SQLite, то только оно имеет к ней доступ. Поставщик содержимого применяется лишь в тех случаях, когда необходимо использовать данные совместно с другими приложениями, работающими на устройстве. Запускается в главном потоке приложения, поэтому для обработки запросов к базе данных, необходимо использовать другой поток. Например при помощи ContentProvider мы можем получить контакты из записной книги телефона или SMS.
7. Что такое ContentResolver?
ContentResolver необходим для выполнения запросов к ContentProvider другого приложения. ContentResolver включает в себя методы CRUD (create, retrieve, update, delete) для запросов и транзакций. Объекту ContentResolver необходимо передать путь URI, в котором указано, к какому объекту ContentProvider необходимо обращаться.
Читайте также: