Полный список
В этом уроке мы:
— создадим и вызовем второе Activity в приложении
Урок был обновлен 12.06.2017
Мы подобрались к очень интересной теме. На всех предыдущих уроках мы создавали приложения, которые содержали только один экран (Activity). Но если вы пользуетесь смартфоном с Android, то вы замечали, что экранов в приложении обычно больше. Если рассмотреть, например, почтовое приложение, то в нем есть следующие экраны: список аккаунтов, список писем, просмотр письма, создание письма, настройки и т.д. Пришла и нам пора научиться создавать многоэкранные приложения.
Application/Library name: TwoActivity
Module name: p0211twoactivity
Package name: ru.startandroid.p0211twoactivity
Откроем activity_main.xml и создадим такой экран:
На экране одна кнопка, по нажатию которой будем вызывать второй экран.
Открываем MainActivity.java и пишем код:
Мы определили кнопку btnActTwo и присвоили ей Activity в качестве обработчика. Реализация метода onClick для кнопки пока заполнена частично — определяем, какая кнопка была нажата. Чуть позже здесь мы будем вызывать второй экран. Но сначала этот второй экран надо создать.
Если помните, при создании проекта у нас по умолчанию создается Activity.
От нас требуется только указать имя этого Activity – обычно мы пишем здесь MainActivity. Давайте разбираться, что при этом происходит.
Мы уже знаем, что создается одноименный класс MainActivity.java – который отвечает за поведение Activity. Но, кроме этого, Activity «регистрируется» в системе с помощью манифест-файла — AndroidManifest.xml.
Давайте откроем этот файл:
Нас интересует тег application. В нем мы видим тег activity с атрибутом name = MainActivity. В activity находится тег intent-filter с определенными параметрами. Пока мы не знаем что это и зачем, сейчас нам это не нужно. Забегая вперед, скажу, что android.intent.action.MAIN показывает системе, что Activity является основной и будет первой отображаться при запуске приложения. А android.intent.category.LAUNCHER означает, что приложение будет отображено в общем списке приложений Android.
Т.е. этот манифест-файл — это что-то типа конфигурации. В нем мы можем указать различные параметры отображения и запуска Activity или целого приложения. Если в этом файле не будет информации об Activity, которое вы хотите запустить в приложении, то вы получите ошибку.
Android Studio при создании модуля создала MainActivity и поместила в манифест данные о нем. Если мы надумаем сами создать новое Activity, то студия также предоставит нам визард, который автоматически добавит создаваемое Activity в манифест.
Давайте создадим новое Activity
Жмем правой кнопкой на package ru.startandroid.p0211twoactivity в папке проекта и выбираем New -> Activity -> Empty Activity
В появившемся окне вводим имя класса – ActivityTwo, и layout – activity_two.
Класс ActivityTwo создан.
В setContentView сразу указан layout-файл activty_two.
Он был создан визардом
Откройте activty_two.xml и заполните следующим кодом:
Экран будет отображать TextView с текстом «This is Activity Two».
Сохраните все. Класс ActivityTwo готов, при отображении он выведет на экран то, что мы настроили в layout-файле two.xml.
Давайте снова заглянем в файл манифеста
Появился тег activity с атрибутом name = .ActivityTwo. Этот тег совершенно пустой, без каких либо параметров и настроек. Но даже пустой, он необходим здесь.
Нам осталось вернуться в MainActivity.java и довершить реализацию метода onClick (нажатие кнопки), а именно — прописать вызов ActivityTwo. Открываем MainActivity.java и добавляем строки:
(добавляете только строки 2 и 3)
Обновите импорт, сохраните все и можем всю эту конструкцию запускать. При запуске появляется MainActivity
Нажимаем на кнопку и переходим на ActivityTwo
Код вызова Activity пока не объясняю и теорией не гружу, урок и так получился сложным. Получилось много текста и скриншотов, но на самом деле процедура минутная. Поначалу, возможно, будет непонятно, но постепенно втянемся. Создадим штук 5-6 новых Activity в разных проектах и тема уляжется в голове.
Пока попробуйте несколько раз пройти мысленно эту цепочку действий и усвоить, что для создания Activity необходимо создать класс (который наследует android.app.Activity) и создать соответствующую запись в манифест-файле.
На следующем уроке:
— разбираемся в коде урока 21
— теория по Intent и Intent Filter (не пропустите, тема очень важная)
— немного о Context
Присоединяйтесь к нам в Telegram:
— в канале StartAndroid публикуются ссылки на новые статьи с сайта startandroid.ru и интересные материалы с хабра, medium.com и т.п.
— в чатах решаем возникающие вопросы и проблемы по различным темам: Android, Kotlin, RxJava, Dagger, Тестирование
— ну и если просто хочется поговорить с коллегами по разработке, то есть чат Флудильня
— новый чат Performance для обсуждения проблем производительности и для ваших пожеланий по содержанию курса по этой теме
Источник
Activity (Активность, Операция)
Activity — это компонент приложения, который является одним из его фундаментальных строительных блоков. Его основное предназначение заключается в том, что оно служит точкой входа для взаимодействия приложения с пользователем, а также отвечает за то, как пользователь перемещается внутри приложения или между приложениями.
По сути активити — это окно, с которым пользователь взаимодействует. И в этом окне можно “нарисовать” какой-либо пользовательский интерфейс. При этом окно может быть как на весь экран, так и занимать только заданную его часть и даже размещаться поверх других окон. Но, как правило, каждая активити реализует только одно окно. Однако, у каждого приложения может быть несколько активити.
Одна из активити может быть отмечена как основная (или главная) и тогда она будет появляться первой при запуске приложения. А уже из нее можно запустить другие активити. Причем не только те, которые принадлежат текущему приложению, но и активити из других приложений. Может показаться, что все запускаемые активити являются частями одного приложения. На самом же деле они могут быть определены в разных приложениях и работать в разных процессах.
Мне встречалась интересная аналогия, что активити — это как страницы разных сайтов, открываемых в браузере по ссылке.
Создание новой активити
Первым делом следует создать новый класс, который должен наследоваться от класса Activity и переопределять метод onCreate() .
Таким образом мы получим пустое окно. Чтобы в этом окне хоть что-то отображалось нужно создать разметку — layout. Добавляется она в ресурсах (папка res) в подпапке layout.
Теперь эту разметку нужно “подключить” к активити в методе onCreate() .
Ну и наконец, чтобы приложение могло использовать только что созданную активити её нужно объявить в манифесте приложения при помощи элемента .
Все вышеперечисленные шаги можно сократить до одного благодаря наличию в Android Studio стандартных шаблонов: правой кнопкой мыши вызываем контекстное меню и в нём выбираем New -> Activity -> “выбрать нужный шаблон”.
После этого класс, разметка, а также запись в манифесте будут добавлены автоматически.
Настройка активити в манифесте
Рассмотрим более подробно, какую информацию нужно или можно добавлять для элемента в манифесте.
Объявление активити
Как упоминалось выше, все активити приложения обязательно нужно регистрировать в манифесте. Для этого предназначен элемент . У этого элемента есть только один обязательный атрибут — android:name , который ссылается на имя класса активити.
При этом, если приложение уже опубликовано, то не следует менять имя класса, так как это может привести к негативным последствиям. Для часто используемого приложения пользователь, как правило, создает ярлык на главном экране устройства. Ярлык представляет из себя Intent , который, используя имя класса, указывает какой компонент должен быть запущен. Поэтому при смене имени класса сломаются все ярлыки, а пользователь будет недоволен.
Помимо обязательного атрибута существуют и другие, с помощью которых каждой активити можно задать уникальные заголовок, иконку, тему и многие другие характеристики. Подробнее с ними можно ознакомиться в моей статье про манифест или в официальной документации.
Объявление intent-фильтров
Скорее всего данная тема будет не особо понятна новичкам, поэтому сначала рекомендую ознакомиться с тем, что такое Intent.
Intent-фильтры — это выражение в файле манифеста, которое указывает, какие объекты Intent может обработать текущее приложение. Т.е. они позволяют настроить, на что будет реагировать активити.
Если у приложения отсутствуют intent-фильтры, то запустить его можно будет только с помощью явного Intent (по имени класса).
Например, активити можно добавить intent-фильтр, который будет говорить, что она умеет отправлять данные.
Выше упоминалось, что активити можно отметить как основную. Это тоже осуществляется с помощью intent-фильтра.
Объявление разрешений
С помощью разрешений можно контролировать, какие приложения могут запускать активити. При этом одна активити не сможет запустить другую, если они не имеют одинаковых разрешений в манифесте.
Например, ваше приложение хочет использовать приложение SocialApp для публикации какой-либо информации в социальных сетях. Приложение SocialApp должно определить разрешение:
И чтобы иметь возможность запускать SocialApp вы должны в своем приложении добавить идентичное разрешение:
Жизненный цикл
При использовании приложения мы постоянно перемещаемся от одного экрана к другому и обратно. Поэтому все активити, с которыми мы взаимодействуем постоянно меняют состояние своего жизненного цикла. А чтобы узнать о смене состояния существуют методы обратного вызова. Т.е. как только активити перешла в другое состояние, сразу же вызывается соответствующий метод обратного вызова. Таким образом можно отслеживать смену состояния и реагировать на него.
Для чего это делать? Чтобы избежать следующих ситуаций:
- Сбой приложения, когда пользователю поступает звонок или когда он переключается на другое приложение.
- Потребление ценных ресурсов, даже если пользователь активно не пользуется приложением в данный момент.
- Потеря прогресса пользователя, если он переключился на другое приложение или временно из него вышел.
- Сбой или потеря прогресса при смене ориентации экрана с портретной на альбомную и обратно.
Это вовсе не означает, что каждый раз нужно реализовывать все методы обратного вызова. Требуется лишь понять для чего каждый из них предназначен, чтобы использовать их в нужный момент.
Методы обратного вызова
onCreate()
Вызывается при создании и перезапуске активити. После создания активити она переходит в состояние “Создана” (Created state), но существует в нём недолго. Как только метод onCreate() будет выполнен, активити переходит в статус “Запущена” (Started state).
Этому методу передается объект Bundle , который содержит в себе сохранённое состояние активити (если она перезапустилась), либо null (если активити ранее не существовала).
Что в нём должно происходить:
Выполнение базовой логики запуска приложения, которая должна происходить только один раз за весь период действия. Например, создание пользовательского интерфейса, привязка данных, создание сервисов (service) и потоков.
Следующий метод:
onStart() .
onStart()
Вызывается при переходе активити в состояние “Запущена” (Started state), т.е. сразу после выполнения метода onCreate() . В этом состоянии активити существует пока метод onStart() не будет выполнен. После чего переходит в состояние “Возобновлена” (Resumed state).
Также этот метод делает активити видимой для пользователя, но с ней еще нельзя взаимодействовать.
Что в нём должно происходить:
Выполнение кода, который поддерживает пользовательский интерфейс
Следующий метод:
onResume()
onResume()
Вызывается при переходе активити в состояние “Возобновлена” (Resumed state), т.е. сразу после выполнения метода onStart() . В этом состоянии активити взаимодействует с пользователем. И продолжается это до тех пор пока пользователя что-то не отвлечёт, например, телефонный звонок, переход к другому приложению или отключение экрана устройства. В этом случае активити перейдёт в состояние “Приостановлена” (Paused state).
Что в нём должно происходить:
Включение функциональности, которая должна работать, пока активити видна и находится на переднем плане. Возобновить работу того, что было приостановлено в методе onPause() .
Следующий метод:
onPause()
onPause()
Вызывается, когда активити теряет фокус и переходит в состояние “Приостановлена” (Paused state). Т.е. активити больше не находится на переднем плане, хотя может быть всё ещё видна пользователю.
Завершение работы метода onPause() не означает, что активити перейдёт в другое состояние. Она будет оставаться в состоянии “Приостановлена” до тех пор, пока либо не перейдёт обратно на передний план (вызовется метод onResume() ), либо пока полностью не станет невидимой (вызовется метод onStop() ).
Что в нём должно происходить:
Приостановка или настройка операций, которые не должны продолжаться пока активити находится в состоянии “Приостановлена”, но ожидается, что вы вскоре их возобновите.
Код должен быть легковесным, так как нет гарантии, что он успеет выполнится.
Следующий метод:
onResume() или onStop() .
onStop()
Вызывается, когда активити больше не видна пользователю и переходит в состояние “Остановлена”. Это может произойти, если активити уничтожается, запускается новая активити или возобновляет работу существующая активити, закрывая собой текущую. Несмотря на это, активити остаётся в памяти, но она больше не привязана к диспетчеру окон.
Из состояния “Остановлена” активити либо возвращается к взаимодействию с пользователем (вызывается метод onRestart() ), либо завершается (вызывается метод onDestroy() ).
Что в нём должно происходить:
Остановка функций, работа которых не нужна пока активити невидима для пользователя. Например, остановка анимаций, сохранение информации в базе данных.
Следующий метод:
onRestart() или onDestroy() .
onRestart()
Вызывается, когда активити в состоянии “Остановлена” повторно отображается пользователю.
Что в нём должно происходить:
Выполнение действий, которые должны выполняться при повторном запуске активити в рамках одного жизненного цикла приложения.
Следующий метод:
onStart() .
onDestroy()
Вызывается перед тем, как активити будет уничтожена и переходит в состояние “Уничтожена” (Destroyed state). Это происходит в следующих случаях: если пользователь её закрыл; был вызван метод finish() ; произошла смена конфигурации активити (например, поворот экрана). При этом в первых двух случаях метод onDestroy() будет последним обратным вызовом в жизненном цикле активити. Если же onDestroy() был вызван из-за смены конфигурации, система немедленно создаст новый экземпляр активити и вызовет для него метод onCreate() .
Что в нём должно происходить:
Освобождение всех оставшихся ресурсов, которые не были освобождены в методах onPause() и onStop() .
Не использовать для какой-либо критически важной логики, так как данный метод может быть и не вызван.
Следующий метод:
Последний метод жизненного цикла.
Схема состояний активити
Исходя из вышеописанного можно сделать простенькую схему для лучшего понимания того, как активити переходит из одного состояния своего жизненного цикла в другое. Я делаю акцент именно на состояниях (а не на методах обратного вызова), потому что на мой взгляд это легче для восприятия (особенно новичкам).
Источник