Основные компоненты приложения.
Context
- Context – это объект, который предоставляет доступ к базовым функциям приложения
- доступ к ресурсам, к файловой системе, вызов активности и т.д.
- Activity является подклассом Context
- в коде мы можем использовать её как ИмяАктивности.this (напр. MainActivity.this)
- Доступ к контексту можно получить разными способами: getApplicationContext(), getContext(), getBaseContext()
Context
- Context имеет свои методы, позволяющие получать доступ к ресурсам и другим объектам: getAssets(), getResources(), getPackageManager(), getString(), getSharedPrefsFile().
- getAssets(): приложение может иметь ресурсы в папке assets вашего проекта
- getResources: получить доступ к ресурсу цвета используется конструкция getResources().getColor(), которая может получить доступ к данным из файла res/colors.xml.
Context
- Ключевое слово this не работает в анонимных классах
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(MainActivity.this, "Мяу", Toast.LENGTH_SHORT).show();
}
});
ContextCompact
- В библиотеки совместимости появился свой класс для контекста ContextCompat.
- Может вам пригодиться, когда студия вдруг подчеркнёт метод в старом проекте и объявит его устаревшим.
// Старый метод
context.getResources().getColor(R.color.some_color_resource_id);
// Студия ругается, что нужно использовать новый вариант getColor(int, Theme)
public void onClick(View view) {
int color = getResources().getColor(R.color.colorPrimary); // ругается
Button button = (Button) findViewById(R.id.button);
button.setTextColor(color);
}
// Теперь не ругается
int color = ContextCompat.getColor(this, R.color.colorPrimary);
Activity
Объявление activity в AndroidManifest
<activity
android:name="com.example.app.ChildActivity"
android:label="@string/title_child_activity"
<!-- Parent activity meta-data to support API level 4+ -->
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.example.app.MainActivity" />
<intent-filter>
</intent-filter>
</activity>
Объявление activity в AndroidManifest
- name - java или kotlin класс, который описывает activity
- label - название на верхней панели.
- intent-filter - события, на которые будет реагировать экран.
- множество других параметров (подробнее).
Жизненный цикл activity
Жизненный цикл activity.
- Набор методов управленияе activity
- жёстко контролируется системой и зависит от нужд пользователя, доступных ресурсов и т. д.
- Решение о запуске приложения принимает система.
- Хотя последнее слово и остаётся за системой, она подчиняется определённым заданным и логическим правилам, позволяющим определить, можно ли загрузить, приостановить приложение или прекратить его работу.
- Если в данный момент пользователь работает с определённым окном, система даёт приоритет соответствующему приложению.
- И наоборот, если окно невидимо и система решает, что работу приложения необходимо остановить, чтобы мобилизовать дополнительные ресурсы, будет прекращена работа приложения, имеющего более низкий приоритет.
Жизненный цикл activity. onCreate
- вызывается при создании экземпляра класса activity.
- устанавливается разметка activity setContentView()
- Внутри данного метода настраивают статический интерфейс активности.
- после вызова метода activity переходит в состояние Created.
- Инициализирует статические данные активности, связывают данные со списками и т.д.
- Связывает с необходимыми данными и ресурсами. Задаёт внешний вид через метод setContentView().
Жизненный цикл activity. onCreate
- принимает объект Bundle, содержащий состояние пользовательского интерфейса, сохранённое в последнем вызове обработчика onSaveInstanceState.
- Операции по инициализации, занимающие много времени, следует выполнять в фоновом процессе, а не с помощью метода onCreate().
- В противном случае можно получить диалоговое окно ANR (Application Not Responding, приложение не отвечает).
- В методе можно сделать проверку, запущено ли приложение впервые или восстановлено из памяти.
- Если значение переменной savedInstanceState будет null, приложение запускается первый раз:
Жизненный цикл activity
if ( savedInstanceState == null ) // приложение запущено впервые
{
currentBillTotal = 0.0; // инициализация суммы счета нулем
// другой код
}
else // приложение восстановлено из памяти
{
// инициализация суммы счета сохранённой в памяти суммой
currentBillTotal = savedInstanceState.getDouble(BILL_TOTAL);
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putDouble(BILL_TOTAL, currentBillTotal);
}
Жизненный цикл activity. onStart
- За onCreate() всегда следует вызов onStart()
- перед onStart() не обязательно должен идти onCreate(), так как onStart() может вызываться и для возобновления работы приостановленного приложения (приложение останавливается методом onStop())
- При вызове onStart() окно ещё не видно пользователю, но вскоре будет видно.
- Вызывается непосредственно перед тем, как активность становится видимой пользователю.
- Сопровождается вызовом метода onResume(), если активность получает передний план, или вызовом метода onStop(), если становится скрытой.
Жизненный цикл activity. onResume
- Метод onResume() вызывается после onStart(), даже когда окно работает в приоритетном режиме и пользователь может его наблюдать.
- В этот момент пользователь взаимодействует с созданным вами окном.
- Приложение получает монопольные ресурсы.
- Запускает воспроизведение анимации, аудио и видео. Также может вызываться после onPause().
- система вызывает этот метод каждый раз, когда ваша активность идёт на переднем плане, в том числе, при первом создании.
- Таким образом, вы должны реализовать onResume() для инициализации компонентов, регистрации любых широковещательных приёмников или других процессов, которые вы освободили/приостановили в onPause()
- выполнять любые другие инициализации, которые должны происходить, когда активность вновь активна.
Жизненный цикл activity. onResume
- не нужно перезагружать состояние пользовательского интерфейса внутри него, так как эти функции возложены на обработчики onCreate() и onRestoreInstanceState.
- Пытайтесь размещать относительно быстрый и легковесный код, чтобы ваше приложение оставалось отзывчивым при скрытии с экрана или выходе на передний план.
- Например, после метода onPause(), в котором мы приостановили работу камеры (см. ниже) снова запускаем камеру:
@Override
public void onResume() {
super.onResume();
// Get the Camera instance as the activity achieves full user focus
if (mCamera == null) {
initializeCamera(); // Local method to handle camera init
}
}
Жизненный цикл activity. onPause
- Когда пользователь решает перейти к работе с новым окном, система вызовет для прерываемого окна метод onPause().
- По сути происходит свёртывание активности.
- Деактивирует и выпускает монопольные ресурсы.
- Останавливает воспроизведение видео, аудио и анимацию.
- В этом методе необходимо остановить анимацию и другие действия, которые загружают процессор. Зафиксировать несохранённые данные, например, черновик письма, потому как после его выполнения работа активности может прерваться без предупреждения. Освободить системные ресурсы, например, обработку данных от GPS.
- Исходя из архитектуры своего приложения, вы также можете приостановить выполнение потоков, процессов или широковещательных приёмников, пока активность не появится на переднем плане.
Жизненный цикл activity. onPause
- Когда активность приостановлена, то все компоненты сохраняются в памяти и при возобновления нет необходимости повторно инициализировать их.
- Например, при работе с камерой метод используется следующим образом:
@Override
public void onPause() {
super.onPause();
// Release the Camera because we don't need it when paused
// and other activities might need to use it.
if (mCamera != null) {
mCamera.release()
mCamera = null;
}
}
Жизненный цикл activity. onStop
- Метод onStop() вызывается, когда окно становится невидимым для пользователя.
- Это может произойти при её уничтожении, или если была запущена другая активность (существующая или новая), перекрывшая окно текущей активности.
- Когда ваша активность останавливается, объекты активности хранятся в памяти и восстанавливаются, когда активность возобновляет свою работу.
- Даже если система закрыла вашу активность, когда она была остановлена, она по-прежнему сохраняет состояние объектов, таких как текст в EditText в специальном объекте Bundle (в виде ключ-значение) и восстанавливает их, если пользователь переходит обратно к тому же экземпляру активности.
- При нехватке памяти система может уничтожить скрытую активность, минуя метод onStop() с вызовом метода onDestroy().
Жизненный цикл activity. onRestart
- Если окно возвращается в приоритетный режим после вызова onStop(), то в этом случае вызывается метод onRestart().
- Т.е. вызывается после того, как активность была остановлена и снова была запущена пользователем.
- Всегда сопровождается вызовом метода onStart().
- onRestart предшествует вызовам метода onStart() (кроме самого первого).
- Используйте его для специальных действий, которые должны выполняться только при повторном запуске активности в рамках «полноценного» состояния.
Жизненный цикл activity. onDestroy
- Метод вызывается по окончании работы активности, при вызове метода finish()
- Или в случае, когда система уничтожает этот экземпляр активности для освобождения ресурсов.
- Эти два сценария уничтожения можно определить вызовом метода isFinishing().
- Вызывается перед уничтожением активности.
- Это последний запрос, который получает активность от системы.
- Если определённое окно находится в верхней позиции в стеке, но невидимо пользователю и система решает завершить это окно, вызывается метод onDestroy().
Последовательности вызовов
- Запуск приложения: onCreate() → onStart() → onResume()
- Нажимаем кнопку Назад для выхода из приложения: onPause() → onStop() → onDestroy()
- Нажата кнопка Домой: onPause() → onStop()
- После нажатия кнопки Домой, когда приложение запущено из списка недавно открытых приложений или через значок
onRestart() → onStart() → onResume()
- Когда запускается другое приложение из области уведомлений или открывается приложение Настройки onPause() → onStop()
- Нажата кнопка Назад в другом приложении или в Настройках и ваше приложение стало снова видимым.
onRestart() → onStart() → onResume()
- Открывается диалоговое окно
onPause()
Последовательности вызовов
- Диалоговое окно закрывается onResume()
- Кто-то звонит на телефон onPause() → onResume()
- Пользователь отвечает на звонок onPause()
- Разговор окончен onResume()
- Экран телефона гаснет: onPause() → onStop()
- Экран снова включён onRestart() → onStart() → onResume()
Порядок вызовов
- После onCreate() - onStart()
- После onRestart() - onStart()
- После onStart() - onResume() или onStop()
- После onResume() - onPause()
- После onPause() - onResume() или onStop()
- После onStop() - onRestart() или onDestroy()
- После onDestroy() - ничего