Основные компоненты приложения.

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() - ничего