OnCreate() после завершения() в onStop()

У меня есть активность Android, которая вызывает finish() внутри него onStop(), поэтому, когда я переключаюсь на другие действия (включая главное меню), активность будет отключена. В этом случае все работает так, как ожидалось.

Однако, когда я снова запускаю приложение (иногда, не всегда), я замечаю, что приложение запускается с использованием того же PID, что и предыдущее, и снова вызывает onCreate(). Я не видел никакого вызова onRestart(), поэтому я предполагаю, что вызов onCreate() выполняется сразу после onStop(), что является нарушением действия lifecyce. Когда приложение использует новый PID, я могу понять, почему вызывается onCreate(), потому что это начало активности.

Кто-нибудь знает, почему это происходит?

Немного о приложении, которое я разрабатываю: это приложение Unity + Vuforia + Android. Я создаю пользовательскую активность, потому что мне нужно создать собственный пользовательский интерфейс на Android (вместо Unity).

Я нашел аналогичную проблему в проекте Android: http://code.google.com/p/android/issues/detail?id=15331, но я не уверен, что причина такая же или нет.

update. Из того, что я вижу из журнала, после вызова finish() нет вызова onDestroy(). Однако, если проблема, о которой я упоминал, происходит (действие запускается с использованием того же процесса), есть вызов onDestroy() в начале действия.

update. Извините за последнее обновление. Здесь я показываю выдержку logcat.

## First run

I/ActivityManager(  265): Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=the.app/the.app.UnityAriusActivity bnds=[238,115][351,273] } from pid 423
I/ActivityManager(  265): Start proc the.app for activity the.app/the.app.UnityAriusActivity: pid=1686 uid=10013 gids={3003, 1006, 1015}
D/arius   ( 1686): UnityAriusActivity: onStart
D/arius   ( 1686): UnityAriusActivity: onResume

## Home button is pressed

I/ActivityManager(  265): Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.HOME] flg=0x10200000 cmp=com.sonyericsson.home/.HomeActivity } from pid 265
D/arius   ( 1686): UnityAriusActivity: onPause
D/arius   ( 1686): UnityAriusActivity: onStop

## Second run

I/ActivityManager(  265): Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=the.app/the.app.UnityAriusActivity bnds=[238,115][351,273] } from pid 423

## Same process, onStart is called again

D/arius   ( 1686): UnityAriusActivity: onStart
D/arius   ( 1686): UnityAriusActivity: onResume
I/ActivityManager(  265): Displayed the.app/the.app.UnityAriusActivity: +500ms
D/Unity   ( 1686): Creating OpenGL ES 2.0 context (RGB16 565 16/0)
W/IInputConnectionWrapper(  423): showStatusIcon on inactive InputConnection
I/QCAR    ( 1686): onSurfaceCreated

## Strangely, there an onDestroy here

D/arius   ( 1686): UnityAriusActivity: onDestroy

## Unity apparently kills the process from its onDestroy

I/Process ( 1686): Sending signal. PID: 1686 SIG: 9
I/ActivityManager(  265): Process the.app (pid 1686) has died.

Проблема в том, что во втором прогоне существует onDestroy() после onStart(). Моя деятельность в основном является подклассом деятельности Vuforia/QCAR, которая также является подклассом деятельности Unity. Итак, внутри my onDestroy() я делаю вызов суперкласса '(super.onDestroy()), а также тот же для других методов, которые я переопределяю.

Если бы я посмотрел библиотеку Android Unity и Vuforia/QCAR (мне было любопытно, поэтому я декомпилировал их - да, это может быть неправильно), внутри Unity onDestroy() Unity пытается убить свой собственный процесс (который является процесс приложения).

Process.killProcess(Process.myPid());

Итак, когда это произойдет, мое приложение снова выключится. Если во втором прогоне используется другой процесс, этого странного onDestroy() не происходит.

Я также пробовал метод noHistory. Но то же самое все еще происходит:( Когда во втором прогоне используется тот же процесс, появится более поздний onDestroy(), а затем процесс уничтожается Unity.

Ответ 1

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

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

Поскольку запущенная активность является новой, она не получит onRestart() - это произойдет только при перезапуске существующего действия.

Ответ 2

Почему бы вам просто не установить noHistory="true" в записи манифеста активности? Тогда вам не нужно беспокоиться о том, чтобы вручную завершить работу в onStop().

Искать noHistory в http://developer.android.com/guide/topics/manifest/activity-element.html

Или, альтернативно, установите FLAG_ACTIVITY_NO_HISTORY в своем намерении startActivity(). http://developer.android.com/reference/android/content/Intent.html#FLAG%5FACTIVITY%5FNO%5FHISTORY

Ответ 3

В документации по вашей ссылке описание onDestroy:

Последний звонок, который вы получаете до того, как ваша деятельность будет уничтожена. Это может происходят либо потому, что активность заканчивается (кто-то назвал финиш(), или потому, что система временно уничтожает это экземпляр активности для экономии места. Вы можете различать эти два сценария с методом isFinishing().

Пока для onStop:

Вызывается, когда действие больше не отображается пользователю, потому что другая деятельность была возобновлена ​​и охватывает этот. Это может происходят либо потому, что начинается новая деятельность, а существующая предстает перед этим, или этот уничтожается. За ним следует либо onRestart(), если это действие возвращается взаимодействовать с пользователем или onDestroy(), если эта активность уходит.

Это означает, что finish() вызывает onDestroy не onStop, поэтому, когда действие перезапускается, необходимо вызвать onCreate, так как ваш вызов finish() внутри onStop заставит onDestroy запускаться.

Ответ 4

Я сталкиваюсь с аналогичным поведением: onDestroy странно вызывается после onCreate/onStart/onResume, когда начинается действие. У меня нет определенного подтверждения, но я чувствую, что вызов onDestroy соответствует предыдущей активности, а не новой. Но по какой-то причине его выполнение задерживается до тех пор, пока процесс не будет повторно активирован (при запуске нового действия).

Я считаю, что это связано с вызовом "finish()" из onStop. Я заметил в своих журналах, что диспетчер активности жалуется, что активность, о которой сообщалось, остановилась, но больше не остановлена ​​(она фактически заканчивается). Поэтому я задаюсь вопросом, связано ли это с состоянием, в котором работает менеджер активности, в моей активности.

В вашем случае конечным результатом является то, что весь процесс убит из-за вызова onDestroy. Когда ваше новое действие запускается в том же процессе, что и предыдущее, ваше приложение немедленно выйдет.