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. Когда ваше новое действие запускается в том же процессе, что и предыдущее, ваше приложение немедленно выйдет.