onActivityResult () вызывается преждевременно

92

Я запускаю Activity(потомок PreferenceActivity) из моей рабочей активности следующим образом:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == 1458)
        loadInfo();
}

void showSettingsDialog()
{
    startActivityForResult(new Intent().setClass(this, MyConfigure.class), 1458);
}

MyConfigureclass НЕ имеет setResult()вызовов. Фактически, у MyConfigureкласса нет никакого кода, кроме того, OnCreate()где он загружает настройки с помощью addPreferencesFromResource.

Теперь onActivityResultвызывается requestCodeиз 1458преждевременно, сразу после того, MyConfigureдеятельность выполняется. Проверено на эмуляторах 1.6 и 2.1, а также на устройстве 2.1. Есть ли призыв setResult()где-нибудь похоронить PreferenceActivity? Или как еще можно объяснить этот преждевременный звонок?

Обратный звонок Евгения Маевского
источник
1
Действие не заканчивается на setResults (), оно заканчивается на finish (). Можете ли вы показать метод onCreate вашей активности MyConfigure?
Шерил Саймон
Верно, это не так. Однако что-то вызывает setResult () заранее, и мне интересно, что это такое. Код onCreate тривиален: открытый класс MyConfigure расширяет PreferenceActivity {@Override protected void onCreate (Bundle savedInstanceState) {super.onCreate (savedInstanceState); addPreferencesFromResource (R.xml.preferences); }}
Обратный звонок Евгения Маевского
как вы думаете, чтобы узнать, что вызывается setResult?
RoflcoptrException
Именно для этого я и создал вопрос. Чтобы выяснить, почему onActivityResult вызывается преждевременно.
Обратный звонок Евгения Маевского
Что говорит вывод logcat об этом периоде? В частности, тег «ActivityManager», который показывает, какие намерения вызываются.
Christopher Orr

Ответы:

254

Это исправляется изменением режима запуска на singleTop:

    <activity
        android:name=".MainActivity"
        android:launchMode="singleTop">

В Android есть ошибка / функция (?), Которая немедленно сообщает о результате (который еще не установлен) для Activity, объявленного как singleTask(несмотря на то, что действие продолжает выполняться). Если мы изменим launchModeродительскую активность с singleTaskна singleTop, все будет работать, как ожидалось - результат будет сообщен только после того, как действие будет завершено. Хотя такое поведение имеет определенное объяснение ( singleTaskможет существовать только одно действие, и для него может быть несколько ожидающих), это все же не логическое ограничение для меня.

Обратный звонок Евгения Маевского
источник
2
Вроде баг! ^^ очень странное поведение!
Фелипе
7
Если у действия есть режим запуска singleTask, ему не нужно получать результаты от дочерних действий, использующих onActivityResult. Поддействия просто вызывают finish (), а затем начинают основное действие с намерением данных. В основном действии вы должны переопределить метод onNewIntent и обработать полученное намерение.
Ник
43
launchMode = "singleInstance" также вызывает такое поведение
ffleandro 01
1
Похоже, у меня это не сработало, я пробовал singleTop для родительской активности, но безрезультатно. Я также установил флаг намерения в FLAG_ACTIVITY_SINGLE_TOP, хотя теперь запрос показывает правильное значение, но результат всегда 0.
Neon Warge
11
это происходит на Kitkat 4.4.4, а не на Lolipop.
Сомасундарам Махеш
18

Решил проблему после удаления intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);перед звонком fragment.startActivityForResult(intent, 0);.

TPG
источник
1
Спасибо! Это решило мою проблему. Есть ли где-нибудь этому объяснение?
Коннер Харкнесс
В настоящее время в документации для флага есть объяснение: «Этот флаг нельзя использовать, когда вызывающий объект запрашивает результат от запущенного действия». Ну, это не объяснение, а, по крайней мере, предупреждение!
Code Novitiate
5

Я просто удалил все свои кастомные "android: launchMode" из Activity, и все заработало как шарм. Не стоит менять это, если вы не знаете ТОЧНО, что понимает Android ... Android в этом смысле немного сложен.

Фелипе
источник
1

Это случилось со мной, когда у намерения был установлен Intent.FLAG_RECEIVER_FOREGROUNDфлаг.

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

Сэм
источник
-1

Опять же, как и в комментарии Майры, setResult()это не имеет ничего общего с вашей проблемой. по какой-то причине MyConfigureкласс завершает работу, и когда это происходит, PreferenceActivityпросто предполагает, что может быть результат, MyConfigureпотому что вы написали код именно так.

это также происходит, когда вы принудительно отключаете любую активность, начатую с startActivityForResult()...

Итак, я думаю, что лучше сосредоточиться на том, почему ваш MyConfigureкласс принудительно завершен.

оптимистичность
источник
Класс MyConfigure НЕ завершается, ваши предположения неверны, извините. Если бы это было так, не было бы никаких вопросов
Евгений Маевский 'Обратный