← Назад к вопросам

Как ActivityManager понимает что надо вызывать onResume у конкретной Activity

1.2 Junior🔥 121 комментариев
#Android компоненты

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI5 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Механизм вызова onResume() через ActivityManager и стек задач

На самом деле, напрямую ActivityManager не вызывает методы жизненного цикла Activity. Это распространенное заблуждение. ActivityManager (часть системы Android) управляет стеком задач (Task Stack), но непосредственное управление жизненным циклом конкретной Activity делегируется ActivityThread и компоненту под названием ActivityThread.H (обработчик сообщений).

Вот как работает этот процесс:

1. Роль ActivityManager (AM)

ActivityManager — это системный сервис (ActivityManagerService на стороне системы). Он:

  • Управляет стеком задач (back stack) приложений.
  • Отслеживает состояние всех Activity в системе.
  • Принимает решения о том, какая Activity должна быть на переднем плане (resumed), какая — остановлена (paused), а какая — уничтожена (destroyed). Эти решения основаны на действиях пользователя (запуск новой Activity, нажатие кнопки "Назад"), системных событиях (входящий звонок) или командах от приложения.
  • Посылает команды (интенты), но не вызывает методы напрямую.

2. Посредник: ActivityThread и H (Handler)

Каждое приложение работает в своем процессе. Внутри этого процесса существует главный поток (UI Thread) и объект ActivityThread — это точка входа приложения, которая управляет всеми компонентами (Activity, Service) в этом процессе. У ActivityThread есть внутренний класс H, наследник Handler, который обрабатывает системные сообщения.

Когда ActivityManagerService принимает решение изменить состояние Activity, он отправляет IPC-сообщение (через Binder) в процесс приложения. Это сообщение перехватывается ActivityThread, который преобразует его в сообщение для своего обработчика H.

Ключевые сообщения:

  • RESUME_ACTIVITY — команда возобновить Activity.
  • PAUSE_ACTIVITY — команда приостановить Activity.
  • LAUNCH_ACTIVITY — команда запустить новую Activity.

3. Цепочка вызова onResume()

Вот типичный сценарий, когда Activity A запускает Activity B:

  1. Решение системы: ActivityManagerService видит, что Activity A запускает Activity B. Он определяет, что A должна перейти в состояние Paused, а B — в состояние Resumed.
  2. Команда процессу A (пауза): AMS отправляет команду PAUSE_ACTIVITY в процесс приложения для Activity A.
  3. Обработка в процессе: ActivityThread получает команду и через Handler H ставит в очередь сообщение PAUSE_ACTIVITY. В конечном итоге вызывается handlePauseActivity(), который:
    *   Вызывает `Activity.performPause()` → `onPause()` у Activity A.
    *   Сообщает AMS, что пауза завершена.
  1. Команда процессу B (резюме): Получив подтверждение о паузе A, AMS отправляет команду RESUME_ACTIVITY в процесс (или создает его) для Activity B.
  2. Обработка в процессе B: ActivityThread получает команду, через Handler H вызывает handleResumeActivity(). Этот метод выполняет несколько важных шагов:
// Упрощенная схема того, что происходит в handleResumeActivity()
final void handleResumeActivity(IBinder token, ...) {
    // 1. Вызывается performResumeActivity()
    ActivityClientRecord r = performResumeActivity(token, ...);
    
    if (r != null) {
        // 2. performResumeActivity() внутри вызывает:
        // - r.activity.performResume() 
        //   -> который вызывает r.activity.onResume()
        
        // 3. Связывание с WindowManager и делание Activity видимой
        if (r.window == null) {
            r.window = r.activity.getWindow();
            View decor = r.window.getDecorView();
            ViewManager wm = r.activity.getWindowManager();
            wm.addView(decor, l); // View добавляется в WindowManager
        }
        
        // 4. Activity окончательно становится интерактивной
        r.activity.makeVisible();
    }
}

4. Ключевой метод performResumeActivity()

Именно здесь происходит прямой вызов onResume():

public final ActivityClientRecord performResumeActivity(IBinder token, ...) {
    ActivityClientRecord r = mActivities.get(token); // Получаем запись о Activity
    // ...
    try {
        // Внутри этой строки происходит магия:
        r.activity.performResume();
    } catch (Exception e) {
        // ...
    }
    return r;
}

// В классе Activity:
final void performResume() {
    // Вызов onResume()
    onResume();
    
    // Обнуление флага, говорящего, что Activity была остановлена
    mCalled = true;
    // ... 
    // Восстановление состояния фрагментов
    mFragments.dispatchResume();
    // ...
}

Итог и аналогия

Представьте себе диспетчера аэропорта (ActivityManagerService), который решает, какой самолет (Activity) должен взлететь (Resumed), а какой — идти на посадку (Paused). Он отправляет команды пилотам (ActivityThread в каждом процессе-самолете). Пилот (ActivityThread) получает команду "взлетать", выполняет внутреннюю последовательность проверок (handleResumeActivity()) и в нужный момент нажимает рычаг тяги, который непосредственно запускает двигатели (вызывает onResume() у конкретной Activity).

Таким образом, цепочка выглядит так:

  1. Решение принимает ActivityManagerService.
  2. Команда передается через IPC в процесс приложения.
  3. Маршрутизацию внутри UI Thread выполняет ActivityThread.H (Handler).
  4. Непосредственный вызов onResume() осуществляет ActivityThread через performResumeActivity()activity.performResume().

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

Как ActivityManager понимает что надо вызывать onResume у конкретной Activity | PrepBro