Android — Activities
An activity represents a single screen with a user interface just like window or frame of Java.Android activity is the subclass of ContextThemeWrapper class.
If you have worked with C, C++ or Java programming language then you must have seen that your program starts from main() function. Very similar way, Android system initiates its program with in an Activity starting with a call on onCreate() callback method. There is a sequence of callback methods that start up an activity and a sequence of callback methods that tear down an activity as shown in the below Activity life cycle diagram: (image courtesy : android.com )
The Activity class defines the following call backs i.e. events. You don’t need to implement all the callbacks methods. However, it’s important that you understand each one and implement those that ensure your app behaves the way users expect.
Sr.No | Callback & Description | |||||||
---|---|---|---|---|---|---|---|---|
1 |
Step | Description |
---|---|
1 | You will use Android studio to create an Android application and name it as HelloWorld under a package com.example.helloworld as explained in the Hello World Example chapter. |
2 | Modify main activity file MainActivity.java as explained below. Keep rest of the files unchanged. |
3 | Run the application to launch Android emulator and verify the result of the changes done in the application. |
Following is the content of the modified main activity file src/com.example.helloworld/MainActivity.java. This file includes each of the fundamental life cycle methods. The Log.d() method has been used to generate log messages −
An activity class loads all the UI component using the XML file available in res/layout folder of the project. Following statement loads UI components from res/layout/activity_main.xml file:
An application can have one or more activities without any restrictions. Every activity you define for your application must be declared in your AndroidManifest.xml file and the main activity for your app must be declared in the manifest with an that includes the MAIN action and LAUNCHER category as follows:
If either the MAIN action or LAUNCHER category are not declared for one of your activities, then your app icon will not appear in the Home screen’s list of apps.
Let’s try to run our modified Hello World! application we just modified. I assume you had created your AVD while doing environment setup. To run the app from Android studio, open one of your project’s activity files and click Run icon from the toolbar. Android studio installs the app on your AVD and starts it and if everything is fine with your setup and application, it will display Emulator window and you should see following log messages in LogCat window in Android studio −
Let us try to click lock screen button on the Android emulator and it will generate following events messages in LogCat window in android studio:
Let us again try to unlock your screen on the Android emulator and it will generate following events messages in LogCat window in Android studio:
Next, let us again try to click Back button on the Android emulator and it will generate following events messages in LogCat window in Android studio and this completes the Activity Life Cycle for an Android Application.
Источник
Activity
Activity и жизненный цикл приложения
Ключевым компонентом для создания визуального интерфейса в приложении Android является activity (активность). Нередко activity ассоциируется с отдельным экраном или окном приложения, а переключение между окнами будет происходить как перемещение от одной activity к другой. Приложение может иметь одну или несколько activity. Например, при создании проекта с пустой Activity в проект по умолчанию добавляется один класс Activity — MainActivity, с которого и начинается работа приложения:
Все объекты activity представляют собой объекты класса android.app.Activity , которая содержит базовую функциональность для всех activity. В приложении из прошлой темы мы напрямую с этим классом не работали, а MainActivity наследовалась от класса AppCompatActivity . Однако сам класс AppCompatActivity, хоть и не напрямую, наследуется от базового класса Activity.
Жизненный цикл приложения
Все приложения Android имеют строго определенный системой жизненный цикл. При запуске пользователем приложения система дает этому приложению высокий приоритет. Каждое приложение запускается в виде отдельного процесса, что позволяет системе давать одним процессам более высокой приоритет, в отличие от других. Благодаря этому, например, при работе с одними приложениями Android позволяет не блокировать входящие звонки. После прекращения работы с приложением, система освобождает все связанные ресурсы и переводит приложение в разряд низкоприоритетного и закрывает его.
Все объекты activity, которые есть в приложении, управляются системой в виде стека activity, который называется back stack . При запуске новой activity она помещается поверх стека и выводится на экран устройства, пока не появится новая activity. Когда текущая activity заканчивает свою работу (например, пользователь уходит из приложения), то она удаляется из стека, и возобновляет работу та activity, которая ранее была второй в стеке.
После запуска activity проходит через ряд событий, которые обрабатываются системой и для обработки которых существует ряд обратных вызовов:
Схематично взаимосвязь между всеми этими обратными вызовами можно представить следующим образом
onCreate()
onCreate — первый метод, с которого начинается выполнение activity. В этом методе activity переходит в состояние Created. Этот метод обязательно должен быть определен в классе activity. В нем производится первоначальная настройка activity. В частности, создаются объекты визуального интерфейса. Этот метод получает объект Bundle , который содержит прежнее состояние activity, если оно было сохранено. Если activity заново создается, то данный объект имеет значение null. Если же activity уже ранее была создана, но находилась в приостановленном состоянии, то bundle содержит связанную с activity информацию.
После того, как метод onCreate() завершил выполнение, activity переходит в состояние Started , и и система вызывает метод onStart()
onStart
В методе onStart() осуществляется подготовка к выводу activity на экран устройства. Как правило, этот метод не требует переопределения, а всю работу производит встроенный код. После завершения работы метода activity отображается на экране, вызывается метод onResume , а activity переходит в состояние Resumed.
onResume
При вызове метода onResume activity переходит в состояние Resumed и отображается на экране устройства, и пользователь может с ней взаимодействовать. И собственно activity остается в этом состоянии, пока она не потеряет фокус, например, вследствии переключения на другую activity или просто из-за выключения экрана устройства.
onPause
Если пользователь решит перейти к другой activity, то система вызывает метод onPause , а activity переходит в состояние Paused . В этом методе можно освобождать используемые ресурсы, приостанавливать процессы, например, воспроизведение аудио, анимаций, останавливать работу камеры (если она используется) и т.д., чтобы они меньше сказывались на производительность системы.
Но надо учитывать, что в этот состоянии activity по прежнему остается видимой на экране, и на работу данного метода отводится очень мало времени, поэтому не стоит здесь сохранять какие-то данные, особенно если при этом требуется обращение к сети, например, отправка данных по интернету, или обращение к базе данных — подобные действия лучше выполнять в методе onStop() .
После выполнения этого метода activity становится невидимой, не отображается на экране, но она все еще активна. И если пользователь решит вернуться к этой activity, то система вызовет снова метод onResume , и activity снова появится на экране.
Другой вариант работы может возникнуть, если вдруг система видит, что для работы активных приложений необходимо больше памяти. И система может сама завершить полностью работу activity, которая невидима и находится в фоне. Либо пользователь может нажать на кнопку Back (Назад). В этом случае у activity вызывается метод onStop .
onStop
В этом методе activity переходит в состояние Stopped. В этом состоянии activity полностью невидима. В методе onStop следует особождать используемые ресурсы, которые не нужны пользователю, когда он не взаимодействует с activity. Здесь также можно сохранять данные, например, в базу данных.
При этом во время состояния Stopped activity остается в памяти устройства, сохраняется состояние всех элементов интерфейса. К примеру, если в текстовое поле EditText был введен какой-то текст, то после возобновления работы activity и перехода ее в состояние Resumed мы вновь увидим в текстовом поле ранее введенный текст.
Если после вызова метода onStop пользователь решит вернуться к прежней activity, тогда система вызовет метод onRestart . Если же activity вовсе завершила свою работу, например, из-за закрытия приложения, то вызывается метод onDestroy() .
onDestroy
Ну и завершается работа activity вызовом метода onDestroy , который возникает либо, если система решит убить activity в силу конфигурационных причин (например, поворот экрана или при многоконном режиме), либо при вызове метода finish() .
Также следует отметить, что при изменении ориентации экрана система завершает activity и затем создает ее заново, вызывая метод onCreate .
В целом переход между состояниями activity можно выразить следующей схемой:
Расмотрим несколько ситуаций. Если мы работаем с Activity и затем переключаемся на другое приложение, либо нажимаем на кнопку Home, то у Activity вызывается следующая цепочка методов: onPause -> onStop . Activity оказывается в состоянии Stopped. Если пользователь решит вернуться к Activity, то вызывается следующая цепочка методов: onRestart -> onStart -> onResume .
Другая ситуация, если пользователь нажимает на кнопку Back (Назад), то вызывается следующая цепочка onPause -> onStop -> onDestroy . В результате Activity уничтожается. Если мы вдруг захотим вернуться к Activity через диспетчер задач или заново открыв приложение, то activity будет заново пересоздаваться через методы onCreate -> onStart -> onResume
Управление жизненным циклом
Мы можем управлять этими событиями жизненного цикла, переопределив соответствующие методы. Для этого возьмем из прошлой главы класс MainActivity и изменим его следующим образом:
Для логгирования событий здесь используется класс android.util.Log .
В данном случае обрабатываются все ключевые методы жизненного цикла. Вся обработка сведена к вызову метода Log.d() , в который передается TAG — случайное строковое значение и строка, которая выводится в консоли Logcat в нижней части Android Studio, выполняя роль отладочной информации. Если эта консоль по умолчанию скрыта, то мы можем перейти к ней через пункт меню View -> Tool Windows -> Logcat .
И при запуске приложения мы сможем увидеть в окне Logcat отладочную информацию, которая определяется в методах жизненного цикла activity:
Источник
Полный список
— вызываем Activity с возвратом результата
Бывает необходимость вызвать Activity, выполнить на нем какое-либо действие и вернуться с результатом. Например – при создании SMS. Вы жмете кнопку «добавить адресата», система показывает экран со списком из адресной книги, вы выбираете нужного вам абонента и возвращаетесь в экран создания SMS. Т.е. вы вызвали экран выбора абонента, а он вернул вашему экрану результат.
Об этом можно почитать здесь.
Давайте посмотрим на практике. Создадим приложение с двумя экранами. С первого экрана будем вызывать второй экран, там вводить данные, нажимать кнопку и возвращаться на первый экран с введенными данными. Например, будем таким образом запрашивать имя.
Создадим проект:
Project name: P0291_SimpleActivityResult
Build Target: Android 2.3.3
Application name: SimpleActivityResult
Package name: ru.startandroid.develop.p0291simpleactivityresult
Create Activity: MainActivity
Открываем main.xml и нарисуем такой экран:
На экране TextView, который будет отображать имя, и кнопка, которая будет вызывать экран для ввода.
Определяем TextView и кнопку, настраиваем обработчик. В методе обработчика onClick создаем Intent, указываем класс второго Acivity (которое создадим чуть позже, на ошибку не обращайте внимания). Для отправки используем startActivityForResult. Отличие от обычного startActivity в том, что MainActivity становится «родителем» для NameActivity. И когда NameActivity закрывается, вызывается метод onActivityResult в MainActivity, тем самым давая нам знать, что закрылось Activity, которое мы вызывали методом startActivityForResult.
В startActivityForResult в качестве параметров мы передаем Intent и requestCode. requestCode – необходим для идентификации. В этом уроке мы его укажем, но не будем использовать по назначению. В следующем же уроке разберемся подробнее, зачем он нужен.
В onActivityResult мы видим следующие параметры:
requestCode – тот же идентификатор, что и в startActivityForResult. По нему определяем, с какого Activity пришел результат.
resultCode – код возврата. Определяет успешно прошел вызов или нет.
data – Intent, в котором возвращаются данные
requestCode и resultCode мы пока использовать не будем, подробнее рассмотрим их на следующем уроке. А из data мы будем получать объект по имени name и выводить значение в TextView.
Если мы извлекаем из Intent объект с именем name, значит надо, чтобы кто-то его туда положил. Этим займется NameActivity.
Создадим экран name.xml:
В поле ввода будем вводить имя и жать кнопку OK.
Создаем класс NameActivity и прописываем его в манифесте:
Определяем поле ввода и кнопку, прописываем обработчик. В методе onClick мы создаем Intent и помещаем в него данные из поля ввода под именем name. Обратите внимание, мы никак не адресуем этот Intent. Т.е. ни класс, ни action мы не указываем. И получается, что непонятно куда пойдет этот Intent. Но метод setResult знает, куда его адресовать — в «родительское» Activity, в котором был вызван метод startActivityForResult. Также в setResult мы передаем константу RESULT_OK, означающую успешное завершение вызова. И именно она передастся в параметр resultCode метода onActivityResult в MainActivity.java. Это мы подробнее разберем на следующем уроке. Далее методом finish мы завершаем работу NameActivity, чтобы результат ушел в MainActivity.
Все сохраним и запустим приложение.
Видим первый экран:
Жмем кнопку, чтобы попасть на экран ввода имени.
Вводим имя и жмем ОК
Снова первый экран, отобразивший полученные данные.
Попробуем подытожить. В MainActivity мы создали Intent с явным указанием на класс NameActivity. Запустили этот Intent с помощью метода startActivityForResult. NameActivity отобразилось, мы ввели имя и нажали кнопку. Создался Intent, в который поместилось введенное нами имя. Метод setResult знает, что Intent надо вернуть в Activity, которое выполнило вызов startActivityForResult, т.е. – MainActivity. В MainActivity за прием результатов с вызванных Activity отвечает метод onActivityResult. В нем мы распаковали Intent и отобразили полученные данные в TextView.
Пока необходимо просто понять схему вызова и возврата.
На следующем уроке мы сделаем расширенный и более показательный пример использования этой технологии.
На следующем уроке:
— разбираемся, зачем нужны requestCode и resultCode в onActivityResult
Присоединяйтесь к нам в Telegram:
— в канале StartAndroid публикуются ссылки на новые статьи с сайта startandroid.ru и интересные материалы с хабра, medium.com и т.п.
— в чатах решаем возникающие вопросы и проблемы по различным темам: Android, Kotlin, RxJava, Dagger, Тестирование
— ну и если просто хочется поговорить с коллегами по разработке, то есть чат Флудильня
— новый чат Performance для обсуждения проблем производительности и для ваших пожеланий по содержанию курса по этой теме
Источник