Activity Lifecycle

1.

Александр Загоруйко © 2022
Activity Lifecycle

2.

Контрольные вопросы
Три способа обработки события
onClick для кнопки: преимущества и
недостатки каждого подхода
Почему важно хранить строковые
ресурсы в отдельном xml-файле?
Что такое уведомление (Toast)?
Как работает событие onTouch?

3.

План презентации
Горячие
клавиши Android Studio
Live Templates (сниппеты)
Flashlight v.1.0
Состояния активити
Жизненный цикл активити
Логирование (класс Log)
Запрет смены ориентации экрана

4.

План презентации
Сохранение
состояния при повороте
Создание второго активити
Передача данных во второе активити
Отправка почты с помощью интента
Flashlight v.2.0
Голосовой ввод текста
Практика

5.

Горячие клавиши Android Studio
Alt + Enter – быстрое исправление ошибок,
если вариантов исправления несколько –
появится список
Ctrl + Alt + T – заверните в …
Alt + J - мультикурсор

6.

Горячие клавиши
Alt + Shift + C –
недавние изменения
в проекте
Ctrl + H – полная
иерархия типов для
текущего
местоположения в
коде
Ctrl + Shift + R –
поиск и замена
https://proglib.io/p/android-tricks/

7.

Горячие клавиши
Alt + Insert – сгенерировать метод
F4 - перейти к определению
Ctrl + Z – отмена действия
Ctrl + Shift + Z – отмена отмены
Ctrl + Y – удалить строку кода
Shift + F10 – построение и запуск
Ctrl + Alt + L – форматирование кода
Ctrl + Space – завершение имени
класса/метода/переменной
Alt + Left/Right – переключение между
вкладками
http://www.jetbrains.com/idea/docs/IntelliJIDEA_ReferenceCard.pdf

8.

И вот ещё немного об этом
Most Useful Shortcut Keys for Android Studio
with Bonus Plugins:
https://medium.com/@gotoark/most-useful-shortcutkeys-for-android-studio-with-bonus-pluginsbf95c85427f0
Key promoter - shows to user how easy he can
make same action using only keyboard:
https://plugins.jetbrains.com/plugin/4455-keypromoter
Mouseless Driven Development:
https://vimeo.com/98922030

9.

Live Templates
https://medium.com/google-developers/writing-more-code-bywriting-less-code-with-android-studio-live-templates244f648d17c7#.f3iisvm53

10.

Flashlight v.1
Добавить
features и permissions в
файл AndroidManifest.xml
Исходники доступны по ссылке:
https://git.io/v6jWT

11.

Runtime Permissions Libraries
https://github.com/Karumi/Dexter
https://github.com/kayvannj/PermissionUtil
https://github.com/ParkSangGwon/TedPermission
https://github.com/florent37/RuntimePermission
https://github.com/googlesamples/easypermissions

12.

Permission vs. Feature
https://proandroiddev.com/android-q-roles-3237d029585d

13.

Сворачивание и возврат
Даже для такого простого приложения,
как фонарик, было бы очень здорово
реализовать выключение света и
высвобождение ресурсов камеры при
сворачивании / переключении на другое
активити, а также нормальное
включение света при возврате на
активити. Как же отследить
сворачивание и возврат в приложение?

14.

Activity Lifecycle Methods
protected
void onCreate()
protected void onStart()
protected void onRestart()
protected void onResume()
protected void onPause()
protected void onStop()
protected void onDestroy()
https://developer.android.com/reference/android/app/Activity.html

15.

Жизненный цикл Activity
http://developer.alexanderklimov.ru/android/theory/lifecycle.php

16.

Состояния Activity
Resumed (running) – активити полностью видно
на экране, оно находится в фокусе,
пользователь может взаимодействовать с ним
Paused – активити не в фокусе, пользователь
не может с ним взаимодействовать, но - при
этом активити частично видно (оно перекрыто
диалогом, или другим активити, которое не на
весь экран или полупрозрачное)
Stopped – (обычно) активити не видно, оно
полностью перекрывается другим активити
If an activity is paused or stopped, the system can drop the activity from memory by either asking it to finish, or simply
killing its process. When it is displayed again to the user, it must be completely restarted and restored to its previous state.

17.

Lifecycle callback methods
При переходе активити из одного
состояния в другое, система вызывает
для активити один или несколько
callback-методов, которые
свидетельствуют о том, что переход
состоялся.
https://www.youtube.com/watch?v=vv9
w9_l17z4

18.

19.

Проследим за переходами
https://git.io/v6jXE

20.

Если логи не отображаются
http://stackoverflow.com/questions/422864
1/logcat-not-displaying-my-log-calls

21.

Класс Log
API for sending log output.
Generally, use the Log.v() Log.d() Log.i() Log.w() and
Log.e() methods. And if you want, Log.wtf() method.
The order in terms of verbosity, from least to most is
ERROR, WARN, INFO, DEBUG, VERBOSE.
https://developer.android.com/reference/android/ut
il/Log.html
How to log to file:
http://stackoverflow.com/questions/19565685/savinglogcat-to-a-text-file-in-android-device
https://developer.android.com/studio/debug/am-logcat

22.

Logger Library
https://github.com/orhanobut/logger
https://medium.com/a-problem-like-maria/bringingmore-colour-to-android-studio-18bb45017106
https://github.com/JakeWharton/pidcat

23.

Android Studio Debugger
https://developer.android.com/studio/debug/
https://medium.com/@artem_shevchenko/androidstudio-debugging%D0%B1%D0%B0%D0%B7%D0%BE%D0%B2%D1%8B%D0%B5%D0%BF%D0%BE%D0%BD%D1%8F%D1%82%D0%B8%D1%8F-%D0%B8%D0%B2%D0%BE%D0%B7%D0%BC%D0%BE%D0%B6%D0%BD%D0%BE%D1%81
%D1%82%D0%B8-658ee6dcc641

24.

Метод onCreate
Вызывается при первом запуске (создании) активити,
либо при перезапуске (если фоновый процесс, хранящий
состояние активити, был остановлен системой, а
пользователь решил вновь перейти на это активити). В
методе onCreate обычно инициализируется графический
интерфейс - привязывается макет (setContentView),
находятся кнопки и другие вьюшки (findViewById).
Операции по инициализации, занимающие много
времени, следует выполнять в фоновом процессе!
В методе можно сделать проверку, запущено ли
приложение впервые или восстановлено из памяти. Если
значение переменной savedInstanceState будет null,
приложение запускается первый раз.
https://developer.android.com/guide/topics/processes/process-lifecycle.html

25.

Метод onStart
Вызывается непосредственно перед
тем, как активити становится
видимым пользователю. Срабатывает
либо после onCreate, либо после
onRestart (в таком случае метод
вызывается для возобновления работы
приостановленного приложения).

26.

Метод onResume
Вызывается после onStart, когда
пользователь может наблюдать за
активити и взаимодействовать с ним.
Приложение получает монопольные
ресурсы. Можно запускать
воспроизведение анимации, аудио и
видео. Также метод может вызываться
после onPause.

27.

Метод onPause
Когда пользователь решит перейти к работе с
другим активити, система вызовет для
прерываемого активити метод onPause. По сути,
происходит свёртывание активити. Здесь
сохраняются незафиксированные данные
(например, черновики писем), деактивируются и
высвобождаются монопольные ресурсы,
останавливается воспроизведение видео, аудио и
анимация. От onPause можно перейти к вызову
либо onResume (если закрыть доп. диалог),
либо onStop (если другое активити перекрывает
наше активити полностью).

28.

Метод onPause
Рекомендуется избегать выполнения
интенсивной работы в onPause, такой как
запись данных в базу, так как это может
существенно замедлить переход к
следующей активности (такие действия
выполняются в onStop). Когда активность
приостановлена, то все компоненты
сохраняются в памяти и при
возобновления нет необходимости
повторно инициализировать их.

29.

Метод onStop
Вызывается, когда активити становится
невидимым для пользователя. Это может
произойти при его уничтожении, или если
было запущено другое активити
(существующее или новое), перекрывшее
окно текущего активити. Вслед за onStop
срабатывает либо onRestart, если активити
восстановлено, чтобы взаимодействовать с
пользователем, либо метод onDestroy, если
активити уничтожается.

30.

Метод onStop
Когда активити останавливается, его объекты
хранятся в памяти, и восстанавливаются, когда
активити возобновляет свою работу. То есть, не
нужно повторно инициализировать компоненты,
которые были созданы ранее. Кроме того,
система отслеживает текущее состояние для
каждого элемента управления, поэтому, если
пользователь введёт текст в текстовое поле, то
текст в нём сохраняется, и программисту не
нужно потом самостоятельно сохранять и
восстанавливать этот текст.

31.

Метод onStop
Даже если система закроет активити,
когда оно было остановлено, состояние
объектов, таких как текст в EditText,
сохраняется в специальном
объекте Bundle (в виде ключ-значение)
и восстанавливается, если
пользователь переходит обратно к тому
же экземпляру активити.

32.

Метод onStop
В этом методе можно сделать сложные
операции по сохранению данных:
приостановку сложной анимации, потоков,
отслеживания показаний датчиков, запросов к
GPS, таймеров, сервисов или других
процессов, которые нужны для обновления
пользовательского интерфейса.
При нехватке памяти система может
уничтожить скрытое активити, без
вызова onStop и onDestroy!

33.

Метод onRestart
Если активити возвращается в приоритетный режим
после вызова onStop, то в этом случае вызывается
метод onRestart. Т.е. вызывается после того, как
активити было остановлено и снова было
запущено пользователем. Вслед за этим методом
всегда вызывается onStart.
onRestart предшествует вызовам метода onStart
(кроме самого первого). Используется для
специальных действий, которые должны
выполняться только при повторном запуске
активности.

34.

Метод onDestroy
Метод вызывается по окончании
работы активити, удаляет все
статические данные, и высвобождает
все используемые ресурсы.
Программное закрытие активити,
отслеживание нажатия Back:
http://developer.alexanderklimov.ru/android/t
heory/activity_methods.php

35.

Практика
Сделать метод-обработчик,
реагирующий на нажатие по кнопке
Back

36.

Особенности onDestroy

37.

38.

Комбинации вызовов
Запуск приложения: onCreate() → onStart() →
onResume()
Кнопка Назад: onPause() → onStop() → onDestroy()
Кнопка Домик: onPause() → onStop()
Открыто диалоговое окно: onPause()
Звонок на телефон: onPause() → onResume()
Экран гаснет: onPause() → onStop()
Экран включается: onRestart() → onStart() →
onResume()
При повороте экрана: onPause() → onStop() →
onDestroy() → onCreate() → onStart() → onResume()

39.

Практика. Сохранение состояния
Создать переменную класса int count = 0;
Сделать кнопку, и обработчик onClick
В обработчике:
Нажать на кнопку несколько раз
Повернуть экран
Ещё несколько раз нажать на кнопку
Сделать выводы

40.

Запрет смены ориентации экрана
В методе onCreate прописать строку:
setRequestedOrientation(
ActivityInfo.
SCREEN_ORIENTATION_PORTRAIT);
(потребуется import
android.content.pm.ActivityInfo;)
и запустить.

41.

Сохранение состояния
Удаляем вызов setRequestedOrientation
Дописываем в класс MainActivity два метода:

42.

Тонкий момент
Нужно ли думать о сохранении состояния, если
приложение поддерживает только портретную
ориентацию?
– Да. Поворот экрана – это частный случай
Configuration Changes. Другой пример – изменение
языка системы.
Кроме того, https://t.me/AndroidSobes/8 , система
может уничтожить активити, чтобы использовать
занятые ей ресурсы. В этом случае состояние
сохраняется и восстанавливается при пересоздании
активити.

43.

Создаём второе активити
Добавляем новое пустое активити
SecondActivity в проект на панели Project:

44.

Создаём второе активити
Меняем тэг в MainActivity.java
String TAG = "FIRST_ACTIVITY";
Обработчик кнопки первого активити:
@Override
public void onClick(View view) {
Intent intent = new Intent(this,
SecondActivity.class);
startActivity(intent);
}
https://blog.usejournal.com/the-journey-of-launching-an-android-activity-9b64e11dc157

45.

Как это работает
https://developer.android.com/training/basics/firstapp/starting-activity.html
отличный урок по переходу на второе активити !!!

46.

Что такое Intent
Intent (намерение) – это класс, объекты которого
используются для взаимодействия между
отдельными частями Android-приложения
(например, двумя активити), либо между
различными приложениями системы: интенты
позволяют отправлять или принимать данные от
других активити и сервисов, а также дают
возможность оповещать о том, что произошло
определённое событие.
https://developer.android.com/reference/android/conte
nt/Intent.html

47.

Создаём второе активити
В
класс SecondActivity добавляем поле
String TAG = "SECOND_ACTIVITY";
Делаем такие же логи в методах
onCreate, onDestroy и тд.
Запускаем, анализируем происходящее:

48.

49.

Обмен данными
Передать данные во второе активити
Получить
данные во втором активити

50.

Практика
Сделать на втором активити кнопку для возврата на
первое активити
Первое активити передаёт значение во второе.
Второе может вернуть это значение назад, но
значение должно быть на 1 больше полученного
Первое активити должно получать значение от
второго активити, и может снова передать его
второму активити, но тоже на 1 больше полученного
Выводить в заголовок активити this.hashCode() + "", и
попытаться понять, что происходит…
Как отправить объект:
http://stackoverflow.com/questions/2139134/how-to-sendan-object-from-one-android-activity-to-another-using-intents

51.

Нормальный возврат
Новый вызов второго активити
@Override
public void onClick(View view) {
Intent intent = new Intent(this,
SecondActivity.class); // явный и.
startActivityForResult(intent, 100);
// 100 – REQUEST CODE
}
http://startandroid.ru/ru/uroki/vse-uroki-spiskom/68-urok-29-vyzyvaemactivity-i-poluchaem-rezultat-metod-startactivityforresult.html

52.

Нормальный возврат
Обработчик кнопки второго активити:
@Override
public void onClick(View view) {
Intent intent = new Intent();
intent.putExtra("smth", "sometext");
setResult(200, intent); // RESULT
finish();
}
http://startandroid.ru/ru/uroki/vse-uroki-spiskom/69-urok-30-podrobneepro-onactivityresult-zachem-nuzhny-requestcode-i-resultcode.html

53.

Нормальный возврат
Добавить
метод в MainActivity
@Override
protected void onActivityResult(int requestCode, int
resultCode,
Intent data) {
super.onActivityResult(requestCode, resultCode, data);
}
String str = data.getStringExtra("smth");
// getSupportActionBar().setTitle(requestCode + " " +
resultCode + " " + str);
getSupportActionBar().setTitle(this.hashCode()+"");

54.

Другое применение интентов
Изменить код обработчика нажатия на кнопку в MainActivity:

55.

Фильтр подходящих приложений
К сожалению, нет простого решения для показа лишь
определённых приложений в стандартном диалоге
выбора. В примере по ссылке ниже интентом будут
вызваны все приложения, название пакета которых
включает сочетание "vk". Как вариант, можно
самостоятельно создать кастомный диалог, в котором
будет отобранный список нужных приложений. О том,
как создать элемент ListView/RecyclerView,
заполнить его информацией при помощи
BaseAdapter, и разместить это всё в
DialogFragment, вы узнаете в следующих занятиях.
https://git.io/vij2b
http://stackoverflow.com/questions/6827407/how-to-customize-share-intent-inandroid/9229654#9229654

56.

Картинка + текст в интенте
По этой же ссылке
https://git.io/vij2b
есть пример того, как передать с
интентом не только текст, но и картинку.

57.

Знакомство с EditText
Java-код и XML-файл разметки:
https://git.io/vifBR

58.

Flashlight v.2
Обновлённый java-код класса
MainActivity:
https://git.io/vifaj

59.

Результаты

60.

Настройки проекта
Где лежит apk-файл?
Как сделать иконки?
https://github.com/google/androidclassyshark - содержимое APK
https://resizeappicon.com/

61.

Настройки проекта
Что делать с иконками?
Онлайн-сервис подготовит все
иконки нужных размеров.
Останется только разложить их
по подкаталогам папки mipmap!

62.

Гугл продвигает круглые иконки

63.

64.

Подготовка изображений
ПКМ по папке Drawable > New > Vector
> Asset > Choose…

65.

Голосовой ввод текста

66.

Голосовой ввод
https://git.io/
viSfV

67.

Домашнее задание
Передать на второе активити через
интент объект типа Cat или Student.
Вытащить из переданного объекта
основные данные, показать их в
заголовке активити, либо тостом.
English     Русский Правила