OnActivityResult() & onResume()

Может ли кто-нибудь сказать мне, что вызывается первым, это onActivityResult() или это onResume()? Пример:

Действие A вызывает startActivityForResult(), чтобы запустить Activity B. B. выполняет, завершает и возвращает результат A, но какой метод A вызывается первым, onActivityResult() или onResume()?

Я знаю, что кто-то уже ответил на этот вопрос, обратившись к Activity Docs, но я не смог найти там сам.

Ответ 1

Первый вызов onActivityResult(), затем onResume().

Цитата из документов:

protected void onActivityResult (int requestCode, int resultCode, Intent данные)

Так как: API Уровень 1 Вызывается, когда деятельность, которую вы запускали, выдает вы запрашиваете код, который вы его запустили с, resultCode он вернулся, и любые дополнительные данные из него. resultCode будет RESULT_CANCELED, если действие явно вернуло это, не возвратил никакого результата или не разбился во время его работы. Вы получите этот вызов непосредственно перед onResume(), когда ваша активность повторный запуск.

Ответ 2

Как уже отмечали другие, onActivityResult() вызывается перед onResume(), когда ваша активность перезапускается.

Диана Хакборн объясняет, что onActivityResult() вызывается перед onResume(), чтобы разрешить все, что может повлиять на пользовательский интерфейс, который должен быть получен и доступен до обновления пользовательского интерфейса (предположительно, чтобы избежать двойного обновления - один раз в onResume() без возвращаемого результата, а затем в onActivityResult(), добавив возвращаемый результат).

https://groups.google.com/forum/?fromgroups=#!topic/android-developers/3epIML7fjGw

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

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

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

Еще один способ справиться с этим - сохранить информацию, возвращаемую функцией onActivityResult(), в переменных, которые будут получены с помощью onResume() и обработаны там (после того, как любые требуемые инициализации были выполнены onResume()), вместо того, чтобы выполнять обработка внутри тела самой onActivityResult().

Эта функция очень документирована, без каких-либо объяснений или предупреждений (в официальных документах) о последствиях этой несколько неожиданной последовательности. Также очень легко упустить проблему во время тестирования, потому что на устройстве с большим количеством памяти, в которой не работает много приложений, активность, вызывающая startActivityForResult() (или ее варианты), может никогда не быть сброшена из памяти, ожидая начал работу, чтобы вернуть результат через onActivityResult(), и поэтому все инициализации, выполняемые onResume(), уже будут доступны, и, следовательно, проблема может быть не обнаружена.

Здесь есть информативное исследование некоторых проблем, связанных с этим секвенированием (включая предупреждение о попытке использования приложения Application object для защиты переменных от его эффектов), в комплекте с диаграммой последовательности UML с рисованием:

http://steveliles.github.com/android_activity_lifecycle_gotcha.html

Ответ 3

onActivityResult() вызывается первым (только что подтвердил это несколькими операторами журнала и посмотрел, что onActivityResult() действительно вызывается до onResume())

Ответ 4

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

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

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