Проблемы с пониманием жизненного цикла, когда экран выключается и включается

информация: Мое устройство - Nexus One с 2.2 и я протестировал два проекта, один на 1.5 и один на 2.1.

Проблема: мне трудно понять жизненный цикл моего приложения при выключении и включении экрана.

Вот мой вывод

// activity starts
08-04 17:24:17.643: ERROR/PlayActivity(6215): onStart executes ...
08-04 17:24:17.643: ERROR/PlayActivity(6215): onResume executes ...
// screen goes off
08-04 17:24:28.943: ERROR/PlayActivity(6215): onPause executes ...
08-04 17:24:32.113: ERROR/PlayActivity(6215): onStop executes ...
08-04 17:24:32.113: ERROR/PlayActivity(6215): onDestroy executes ...
08-04 17:24:32.983: ERROR/PlayActivity(6215): onStart executes ...
08-04 17:24:32.983: ERROR/PlayActivity(6215): onResume executes ...
08-04 17:24:32.983: ERROR/PlayActivity(6215): onPause executes ...
// screen goes on
08-04 17:24:47.683: ERROR/PlayActivity(6215): onResume executes ...
// lock removed
08-04 17:24:56.943: ERROR/PlayActivity(6215): onPause executes ...
08-04 17:24:59.663: ERROR/PlayActivity(6215): onStop executes ...
08-04 17:24:59.663: ERROR/PlayActivity(6215): onDestroy executes ...
08-04 17:25:00.943: ERROR/PlayActivity(6215): onStart executes ...
08-04 17:25:00.943: ERROR/PlayActivity(6215): onResume executes ...

Я совершенно сбит с толку. Зачем перезапускать активность, когда экран гаснет? И зачем останавливать и перезапускать его снова, когда экран уже был включен и только блокировка была снята?

Чтобы убедиться, что я не сделал ничего плохого, я создал новый проект только с этой активностью. Выход одинаковый...

public class LifeCycleTest extends Activity {

    private final static String DEBUG_TAG = "FirstLifeLog";

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.e(DEBUG_TAG, "onCreate executes ...");
        setContentView(R.layout.main);
    }

    protected void onRestart() {
        super.onRestart();
        Log.e(DEBUG_TAG, "onRestart executes ...");
    }

    protected void onStart() {
        super.onStart();
        Log.e(DEBUG_TAG, "onStart executes ...");
    }

    protected void onResume() {
        super.onResume();
        Log.e(DEBUG_TAG, "onResume executes ...");
    }

    protected void onPause() {
        super.onPause();
        Log.e(DEBUG_TAG, "onPause executes ...");
    }

    protected void onStop() {
        super.onStop();
        Log.e(DEBUG_TAG, "onStop executes ...");
    }

    protected void onDestroy() {
        super.onDestroy();
        Log.e(DEBUG_TAG, "onDestroy executes ...");
    }
}

У кого-нибудь есть идея?

Обновление от сегодняшнего дня (не понимаю, почему ведет себя не так, как в прошлый раз, может больше бесплатных ресурсов?)

// activity starts
08-09 12:14:03.122: ERROR/FirstLifeLog(15406): onCreate executes ...
08-09 12:14:03.132: ERROR/FirstLifeLog(15406): onStart executes ...
08-09 12:14:03.132: ERROR/FirstLifeLog(15406): onResume executes ...
// screen off
08-09 12:14:07.412: ERROR/FirstLifeLog(15406): onPause executes ...
// screen on
08-09 12:14:11.722: ERROR/FirstLifeLog(15406): onResume executes ...
// no log for removed screen lock

person WarrenFaith    schedule 04.08.2010    source источник
comment
Странно то, что я вижу вызовы onDestroy(), onStart(), onResume(), но не вижу вызовов onCreate(). Я также заинтересован в понимании поведения.   -  person Catalin Morosan    schedule 05.08.2010
comment
Это потому, что мой onCreate пропустил оператор журнала ... Также я попробовал это сегодня снова ... теперь моя игра ведет себя так же, но тестовый проект имеет ожидаемое поведение (см. Обновление)   -  person WarrenFaith    schedule 09.08.2010


Ответы (4)


См. документацию Жизненный цикл деятельности, где приведено хорошее описание жизненного цикла со схемами. .

Скорее всего ваша активность убивается выключением экрана для экономии ресурсов (заряда батареи). Как говорится в документации, вас могут убить в любой момент, когда Android захочет освободить ресурсы. Таким образом, вы всегда должны проектировать свои действия таким образом, чтобы их можно было остановить и перезапустить в любое время.

person Cheryl Simon    schedule 04.08.2010
comment
Я знаю документацию по жизненному циклу. Убийство для сохранения ресурсов не может быть причиной, потому что оно перезапускается немедленно. И это точно моя проблема. Я не понимаю, почему он убит и сразу же перезапущен. Я многое храню в базе данных, когда запускается onDestroy()... Ненужное приложение уничтожает результаты с длительным временем отклика... - person WarrenFaith; 04.08.2010
comment
Понятно... На самом деле я не проверял эту теорию, но в документации обсуждаются некоторые изменения конфигурации: developer.android.com/reference/android/, которые вызывают перезапуск приложения. Возможно, включение и выключение экрана подходит под uiMode? Несмотря на это, вы можете посмотреть, сможете ли вы сделать onDestroy более эффективным. Может быть, сохранять состояние повсюду, чтобы в этот момент было меньше сохранений? - person Cheryl Simon; 04.08.2010

У меня была такая же проблема с моей собственной игрой. Моя игра работает только в альбомной ориентации, а при выключении экрана управление берет на себя заставка андроида (в портретном режиме), тем самым отправляя ориентациюChange, которая разрушает и воссоздает активность.

Простое решение — объявить, что вы сами будете управлять изменением ориентации экрана:

<activity ... android:configChanges="orientation" ... >

Это довольно просто, если ваша активность объявлена ​​только альбомной (вам ничего не нужно делать), но может стать сложнее, если ваша активность может вращаться...

person Ruben    schedule 14.11.2010
comment
Спасибо! Вероятно, мне потребовалось бы некоторое время, чтобы выяснить это. Могу подтвердить, что происходит с альбомным приложением: воссоздано один раз для изменения на портретное, воссоздано во второй раз после возврата с выключенного экрана. Также работает материал configChanges. Это действительно должно быть должным образом (заметно) задокументировано. - person oberstet; 16.02.2012
comment
Это, вероятно, следует рассматривать как принятый ответ, поскольку, хотя он пришел через месяц, он определяет причину того, что осталось загадочным в другом. - person Chris Stratton; 27.04.2012
comment
Кто-нибудь знает, как обнаружить такой жизненный цикл? Я имею в виду обнаружение того, что onStop вызывается только из-за того, что экран отключается, и что onStart скоро будет выполнен. - person Snicolas; 18.08.2013

Ответ Рубена полностью верен, но только если ваше приложение нацелено на уровень API 12 или ниже.

Но начиная с уровня API 13 в дополнение к опции orientation вы должны объявить опцию screenSize, потому что она также срабатывает, когда устройство переключается между портретной и альбомной ориентацией:

<activity ... android:configChanges="orientation|screenSize" ... >

В противном случае ваша активность все равно будет воссоздана еще раз, когда экран отключится на платформе API 13 или более поздней версии.

Для справки см. документацию по API, android:configChanges примечания к разделу.

person Alexander Abakumov    schedule 26.06.2015

Это способ. Если вы прочитаете жизненный цикл активности, вы увидите, что шаги в значительной степени упорядочены таким образом. Это не только когда ваш экран включается и выключается, но и когда вы меняете ориентацию телефона. Android воссоздал активность, следуя именно тем шагам, которые вы упомянули выше. Попробуйте повернуть экран, тогда увидите! знак равно

person Shouvik    schedule 04.08.2010
comment
Я думаю, что ваше затруднительное положение очень похоже на ситуацию, которую я упомянул выше. У него должно быть что-то с изменяющимися представлениями, чтобы активность убивалась и воссоздавалась для запуска без экрана! Это просто мое предположение... - person Shouvik; 04.08.2010