Почему onDestroy всегда вызывается при возврате к родительской активности?

У меня есть очень простое приложение, основанное на руководстве по Создание вашего первого приложения. Есть два действия: MainActivity вызывает от DisplayMessageActivity до startActivity().

При входе в DisplayMessageActivity вижу:

MainActivity.onStop()

как и ожидалось, но когда я нажимаю кнопку «Назад», чтобы вернуться к родительскому элементу MainActivity, я получаю:

MainActivity.onDestroy()
MainActivity.onCreate(null)
MainActivity.onStart()

Активность всегда уничтожается для этого очень простого приложения. Но, согласно документации (второй пункт), типичное поведение для действия быть остановлен и перезапущен в таких случаях.

Кроме того, onDestroy() не происходит при первом запуске дочерней активности, а только после нажатия кнопки «Назад».

Два вопроса:

  1. Есть ли способ предотвратить уничтожение родителя в общем случае?
  2. Почему здесь null передается onCreate()? Это мешает мне сохранить состояние через onSaveInstanceState().

Обратите внимание, что я проверил, что флажок «Настройки» -> «Параметры разработчика» -> «Приложения» -> «Не сохранять действия» не установлен.

Редактировать:

Вот как дочерняя активность связана с родительской:

    <activity
        android:name="com.example.helloworld.DisplayMessageActivity"
        android:label="@string/title_activity_display_message"
        android:parentActivityName="com.example.helloworld.MainActivity" >
        <meta-data
            android:name="android.support.PARENT_ACTIVITY"
            android:value="com.example.helloworld.MainActivity" />
    </activity>

Проследив DisplayMessageActivity.onOptionsItemSelected(), я вижу, что он звонит Activity.onNavigateUp().


person mtoossi    schedule 28.12.2013    source источник
comment
Вы реализовали onSaveInstanceState() в MainActivity? Вы поворачивали телефон из портретной в альбомную или наоборот во время DisplayMessageActivity?   -  person Greg Giacovelli    schedule 29.12.2013
comment
Я попытался реализовать onSaveInstanceState() в MainActivity. Это помогло, когда экран вращался во время MainActivity. Однако в описанной выше ситуации это было бесполезно, так как onCreate() передается в связке null.   -  person mtoossi    schedule 29.12.2013
comment
На ваш второй вопрос: нет, я не поворачивал телефон во время DisplayMessageActivity. Я пробовал это несколько раз с этим и еще одним приложением, которое я написал, и родительская активность каждый раз уничтожается и создается с пакетом null.   -  person mtoossi    schedule 29.12.2013
comment
Использует ли DisplayMessageActivity большое количество ресурсов? или MainActivity в этом отношении? Совершенно нормально убивать эти действия, но saveInstanceState следует соблюдать, если DisplayMessageActivity просто не запускает новую MainActivity, а не просто завершает и выталкивает из заднего стека   -  person Greg Giacovelli    schedule 29.12.2013
comment
DisplayMessageActivity имеет только TextView, как и в учебнике, на который я ссылался. Я возвращаюсь к MainActivity, нажимая кнопку «Назад» на панели действий.   -  person mtoossi    schedule 29.12.2013
comment
@GregGiacovelli: выше я добавил дополнительные сведения о том, как дочерняя активность связана с родительской. Судя по вашему ответу, действительно создается впечатление, что создается новый MainActivity, так что, может быть, что-то не так с тем, как я связываюсь с родителем?   -  person mtoossi    schedule 29.12.2013


Ответы (2)


Благодаря комментариям Грега Джаковелли я нашел ответ здесь. Решение состояло в том, чтобы установить android:launchMode="singleTop" для родительской активности.

Я до сих пор не могу понять, почему такая базовая информация так неизвестна и ее трудно найти!

person mtoossi    schedule 28.12.2013
comment
Информации много, это как искать иголку в море иголок! - person Steve M; 29.12.2013
comment
+1 ВАУ! Наконец нашел его после двух дней головной боли! Я пытался посмотреть, как можно будет восстановить мои карты в MainAcvitiy после вызова SettingsActivity. Больше не нужно! Я знал, что должен быть выход! Спасибо! - person Eduardo; 28.10.2015
comment
android:launchMode="singleTop" должен быть установлен в основном действии. Сначала я установил его только для активности, начатой ​​​​из основной активности, что, очевидно, не помогло. - person nibarius; 25.08.2017
comment
я использовал SingleTask и столкнулся с этой проблемой. почему у меня это было с singleTask и какая разница? - person Emil; 08.11.2017
comment
В отличие от ответа @Kislingk, это действительно работает. - person NoHarmDan; 22.11.2019

Добавление launchMode в манифест изменяет режим запуска каждый раз, даже если он не запускается дочерней активностью. Существуют и другие способы запуска существующего экземпляра.

1. переопределить onOptionsItemSelected (элемент: MenuItem)

override fun onOptionsItemSelected(item: MenuItem): Boolean {
   return when (item.itemId) {
        android.R.id.home -> {
            // Respond to the action bar's Up/Home button
            val upIntent: Intent? = NavUtils.getParentActivityIntent(this)
            when {
                upIntent == null -> throw IllegalStateException("No Parent Activity Intent")
                else -> {
                    //add launch flag here
                    upIntent.flags=Intent.FLAG_ACTIVITY_CLEAR_TOP
                    NavUtils.navigateUpTo(this, upIntent)
                }
            }
            true
        }
        else -> super.onOptionsItemSelected(item)
    }
}
  1. 2-е решение выглядит как ошибка. Установите для «android:parentActivityName» действие, которого нет в текущем стеке задач. Android будет вести себя как кнопка «НАЗАД». Он запускает верхний экземпляр вместо запуска родительской активности. В документе упоминается, что «NavUtils.shouldUpRecreateTask» может распознавать, существовала ли родительская активность в текущей задаче. Но это не работает в моем тесте. Перейти вверх с новым бэкстеком
person Kislingk    schedule 05.06.2018