Activity

https://developer.android.com/guide/components/activities/intro-activities
https://d.android.com/guide/components/activities/activity-lifecycle
https://developer.android.com/guide/components/activities/state-changes
https://developer.android.com/guide/components/activities/testing
https://developer.android.com/guide/components/activities/tasks-and-back-stack
https://developer.android.com/guide/components/activities/recents
https://d.android.com/guide/components/activities/background-starts

Activity

Представляет UI и функциональность, видимыe пользователю.

• если activity будет убита из-за low memory могут не вызваться killable-методы onStop и onDestroy (onPause до версии 3.0)

• очистить бэкстек при создании activity: использовать флаг FLAG_ACTIVITY_CLEAR_TOP, использовать вместе FLAG_ACTIVITY_CLEAR_TASK и FLAG_ACTIVITY_NEW_TASK

Как пережить поворот экрана?

При повороте экрана активити уничтожается и создается заново. Вызываются коллбэки onPause()onStop()onSaveInstanceState()onDestroy() – onCreate()onStart()onRestoreInstanceState()onResume(). Чтобы сохранить состояние активити, вы должны переопределить метод onSaveInstanceState() и положить данные в Bundle. При реинициализации активити, Bundle с сохраненным состоянием передается в onCreate() и в onRestoreInstanceState(). Система вызывает onSaveInstanceState() и onRestoreInstanceState() только в том случае, когда необходимо сохранить состояние, например при повороте экрана или при убийстве активити для освобождения памяти. Данные коллбэки не вызываются, если пользователь выходит из активити нажав Back или если активити убивается вызовом finish()onSaveInstanceState() вызывается после onStop() на версии API ≥ 28. На API < 28 этот коллбэк вызывается перед onStop() и нет гарантий до или после onPause()onRestoreInstanceState() вызывается после onStart().

Как изменилось поведение onResume и onPause в Android 10?

В Android 10 добавлена поддержка foldables и девайсов с большим экраном. В связи с этим было изменено поведение коллбэков onResume() и onPause() в режиме multi-window. В Android 9 только активити, с которой взаимодействует пользователь, находилась в состоянии resumed, а все остальные активити на экране имели состояние paused. Начиная с Android 10, все видимые активити в режиме multi-window находятся в состоянии resumed. Это поведение называется multi-resume. Активити, с которой взаимодействует пользователь, называется topmost resumed. Для того, чтобы различать resumed и topmost resumed активити, в Android 10 добавлен коллбэк onTopResumedActivityChanged(isTopResumed: Boolean). Этот метод вызывается, когда активити получает или теряет состояние topmost.

Lifecycle

onCreate

Вызывается 1 раз, когда Activity создается. Внутри него вызывается метод setContentView.

onStart

Activity отрисована и видна пользователю.

onResume

Вызывается перед тем, как Activity станет доступна для взаимодействия с пользователем.

onPause

Метод симметричный onResume, пользователь больше не может взаимодействовать с Activity, но она остается видимой.

onStop

Метод симметричный onStart, вызывается, когда Activity больше не видна пользователю.

onDestroy

Метод симметричный onCreate, вызывается перед тем, как Activity будет уничтожена системой.

Launch Modes

standart

Режим запуска Activity по умолчанию в Android. В этом режиме каждый раз, когда Activity запускается, создается новый экземпляр этой Activity, и каждый новый экземпляр помещается в стек задач. При этом Activity может быть создано несколько раз, даже если уже существует экземпляр этой Activity в стеке. Каждый новый экземпляр Activity в режиме standard получает уникальный task и back stack, что позволяет сохранить состояние и историю переходов, обеспечивая независимость между различными экземплярами Activity.

singleTop

Режим запуска Activity, при котором только один экземпляр Activity может быть в стеке задач. Если Activity с singleTop уже находится на вершине стека, новая попытка её запуска не создаст новый экземпляр, а вызовет метод onNewIntent(). Если Activity не на вершине стека, будет создан новый экземпляр.

<activity
    android:name=".YourActivity"
    android:launchMode="singleTop">
</activity>

singleTask

Режим запуска Activity, при котором в одной задаче может существовать только один экземпляр Activity. Если Activity с singleTask уже существует, она будет показана, и все Activity в текущем стеке выше её будут удалены; если нет, она будет создана в новой задаче.

<activity
    android:name=".YourActivity"
    android:launchMode="singleTask">
</activity>

singleInstance

Устанавливает, что Activity будет существовать только в одном экземпляре в своей собственном, отдельном стеке задач (task). Это означает, что если такая Activity уже существует, то новая задача не создаст её экземпляр, а вместо этого вернёт существующий экземпляр.

<activity
    android:name=".YourActivity"
    android:launchMode="singleInstance">
</activity>
taskAffinity

Определяет, к какой задаче (task) принадлежит активность. По умолчанию все активности приложения имеют одинаковую задачу, но с помощью taskAffinity можно задать для активности принадлежность к другой задаче. Task (Задача) — это стек активностей, с которыми взаимодействует пользователь. Если активность имеет другую taskAffinity, она может быть запущена в отдельной задаче или присоединиться к задаче другого приложения с таким же значением taskAffinity. Это полезно, когда нужно контролировать, как активности взаимодействуют с задачами и как они отображаются в списке последних приложений.

• Работает в связке с launchMode активности (например, singleTask, singleTop). Например, если taskAffinity изменён, а launchMode задан как singleTask, активность будет запускаться в своей задаче и перезапускаться, если она уже существует.

• Хорошее объяснение на StackOverflow.

<activity
    android:name=".MainActivity"
    android:taskAffinity=""/>
    
<activity
    android:name=".SettingsActivity"
    android:taskAffinity="com.example.differenttask"/>
TaskStackBuilder

Позволяет создавать и управлять стеком задач для запуска активностей. Он помогает организовать задачи и их историю, чтобы обеспечить правильное поведение навигации при запуске новых активностей. TaskStackBuilder упрощает создание и запуск стека активностей, который будет отображаться в правильном порядке, когда пользователь возвращается к предыдущим активностям.

// Создаем TaskStackBuilder для запуска нового Activity
val stackBuilder = TaskStackBuilder.create(context)

// Добавляем Intent для нового Activity
stackBuilder.addNextIntentWithParentStack(newIntent)

// Запускаем Activity
stackBuilder.startActivities()

addNextIntent

Добавляет новый Intent в стек задач, который будет запущен после текущей активности. Это позволяет создать цепочку активностей и правильно управлять их порядком.

addNextIntentWithParentStack

Позволяет добавить Intent в стек задач с учетом родительской активности. Этот метод гарантирует, что при возврате к предыдущим экранам будет создан правильный стек задач, включая все родительские активности.

ActivityManager

Системный сервис в Android, который управляет жизненным циклом активностей и задач, а также отслеживает состояние процессов в системе. ActivityManager отслеживает все активные, видимые и фоновые активности на устройстве.

val activityManager = getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager

getRunningTasks

Возвращает список задач, которые в настоящее время запущены. Можно указать максимальное количество задач, которые нужно вернуть.

val runningTasks = activityManager.getRunningTasks(10)

getRunningAppProcesses

Возвращает список всех запущенных процессов в системе.

val runningAppProcesses = activityManager.runningAppProcesses

getRecentTasks

Возвращает список недавних задач, которые можно открыть из недавнего меню приложений.

val recentTasks = activityManager.getRecentTasks(10, ActivityManager.RECENT_IGNORE_UNAVAILABLE)

getRunningServices

Возвращает список всех запущенных служб.

val runningServices = activityManager.getRunningServices(10)

getMemoryInfo

Заполняет объект ActivityManager.MemoryInfo информацией о текущем состоянии памяти.

val memoryInfo = ActivityManager.MemoryInfo()
activityManager.getMemoryInfo(memoryInfo)

getProcessMemoryInfo

Возвращает информацию о потреблении памяти для процессов с указанными идентификаторами процессов (PID).

val processMemoryInfo = activityManager.getProcessMemoryInfo(intArrayOf(pid))

killBackgroundProcesses

Завершает все фоновые процессы, связанные с указанным пакетом.

activityManager.killBackgroundProcesses("com.example.myapp")

getAppTasks

Возвращает список задач, связанных с текущими приложениями.

val appTasks = activityManager.appTasks

getLauncherActivities

Возвращает список активностей, которые могут быть запущены из лаунчера.

val launcherActivities = activityManager.launcherActivities
OnBackPressedDispatcher

Управляет обработкой нажатия кнопки “Назад” (Back) в приложении. Позволяет разным частям приложения регистрировать свои обработчики, которые будут вызваны при нажатии кнопки. Пришел на замену методу onBackPressed.

class MainActivity: AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // Регистрируем обработчик нажатия кнопки "Назад"
        onBackPressedDispatcher.addCallback(this, object: OnBackPressedCallback(true) {
            override fun handleOnBackPressed() {
                // Логика при нажатии кнопки "Назад"
                println("Кнопка 'Назад' нажата")
            }
        })
    }
}
Android Activity. Вопросы на собесе
  1. Как пережить поворот экрана? (Смену конфигурации)
  1. Какие методы жизненного цикла Activity вызываются при переходе на следующую Activity?

    Переходим вперед: onPause() onStop()

    Возвращаемся обратно: onStart() onResume()

  1. Какие методы жизненного цикла Activity вызываются при отображении DialogFragment?

    Жизненный цикл не изменяется.

  1. Какие методы жизненного цикла Activity вызываются при отображении/закрытии permission dialog?

    onPause()onResume()

  1. Какие методы жизненного цикла Activity вызываются при переходе в task manager (recent menu)?

    Жизненный цикл не изменяется.

  1. Какие методы жизненного цикла Activity вызываются при смахивании приложения?

    onPause() onStop() onDestroy()

  1. Какие методы жизненного цикла Activity вызываются при сворачивании/разворачивании приложения?

    При сворачивании: onPause() onStop()

    При разворачивании: onStart() onResume()

  1. Какие методы жизненного цикла Activity вызываются при смене ориентации экрана (изменении конфигурации)?

    Activity пересоздается: onPause() onStop()onDestroy()onCreate()onStart()onResume()

  1. Как изменилось поведение onResume и onPause в Android 10?

    В Android 10 методы onResume() и onPause() теперь учитывают многозадачность: onResume() вызывается, когда Activity становится активной, даже если она не на переднем плане, а onPause() вызывается, когда Activity теряет фокус, но может оставаться видимой.

  1. Как запустить стек из нескольких Activity?

    Через TaskStackBuilder в виде стека одним вызовом.

  1. Как запустить Activity в отдельном процессе?

    Указать атрибут android:process в манифесте для этой Activity.

  1. Перечисли все Launch modes?

    standart singleTop singleTask singleInstance

  1. Чем Activity отличается от Fragment?

    Мы легко можем управлять стеком фрагментов. Со стеком активностей возникают проблемы: мы не можем гарантировать их порядок, активити может создастся по интенту другим приложением.

  1. Если запустить Activity2 которая частично перекрывает Activity1, какие коллбэки вызовутся у Activity1?

    onPause()

  1. Жизненный цикл Activity?

    onCreate() onStart() onResume() onPause() onStop() onDestroy()

  1. Когда onDestroy вызовется без onPause и onStop?

    finish() в onCreate()

  1. Можно ли создать приложение без Activity?

    Да, можно. (Приложение обои. Будить через BroadcastReceiver стартовать сервис)

    Нет, у приложения всегда должна быть хотя бы одна активити.