Как вы используете Intent.FLAG_ACTIVITY_CLEAR_TOP для очистки стека активности? - PullRequest
75 голосов
/ 03 декабря 2010

Я прочитал несколько постов об использовании этого, но, должно быть, что-то упустил, потому что это не работает для меня. У моей активности A в манифесте есть launchmode = "singleTop". Начинается действие B с launchmode = "singleInstance". Действие B открывает браузер, получает и возвращает назад, именно поэтому это singleInstance. Я пытаюсь переопределить кнопку «Назад», чтобы отправить пользователя обратно в операцию А, а затем нажать «Назад», чтобы выйти из операции, а не снова вернуться к операции В.

// activity B
@Override
public boolean onKeyDown(int keyCode, KeyEvent event)  {
 if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.ECLAIR
  && keyCode == KeyEvent.KEYCODE_BACK
  && event.getRepeatCount() == 0) onBackPressed();
 return super.onKeyDown(keyCode, event);
}
@Override
public void onBackPressed() {
 startActivity(new Intent(this, UI.class)
 .setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK));
 return;
}

После возвращения из браузера стек ... A, B, браузер, B

Я ожидаю, что этот код изменит стек на ... ... так что повторное нажатие возвращает пользователя на главный экран.

Вместо этого кажется, что стек изменился на ... A, B, браузер, B, A ... как будто этих флагов там нет.

Я попытался вызвать finish () в действии B после startActivity, но затем кнопка «Назад» снова возвращает меня в браузер!

Что мне не хватает? Спасибо!

Ответы [ 10 ]

103 голосов
/ 22 февраля 2012

Я начал Занятие A-> B-> C-> D.Когда кнопка «Назад» нажата на Деятельности D, я хочу перейти к Деятельности А. Поскольку А - моя отправная точка и, следовательно, уже в стеке, все действия в верхней части А очищаются, и вы не можете вернуться к любой другой Деятельности из А.

На самом деле это работает в моем коде:

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_BACK) {
        Intent a = new Intent(this,A.class);
        a.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        startActivity(a);
        return true;
    }
    return super.onKeyDown(keyCode, event);
}       
64 голосов
/ 13 июля 2012

@ bitestar имеет правильное решение, но есть еще один шаг:

Он был скрыт в документах, однако вы должны изменить launchMode из Activity на что-либо, кроме standard.В противном случае он будет уничтожен и воссоздан вместо того, чтобы быть сброшенным на вершину.

19 голосов
/ 20 ноября 2012

Для этого я использую флаг FLAG_ACTIVITY_CLEAR_TOP для запуска Intent(без FLAG_ACTIVITY_NEW_TASK)

и launchMode = "singleTask" в манифесте для запущенного действия.

Похоже, это работает так, как мне нужно - действие не перезапускается, а все остальные действия закрываются.

10 голосов
/ 08 октября 2014

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

Текущий запущенный экземпляр действия B в приведенном выше примере либо получит новое намерение, которое вы запускаете здесь, в его методе onNewIntent (), либо сам будет завершен и перезапущен с новым намерением.

Если он объявил свой режим запуска «множественным» (по умолчанию), и вы не установили FLAG_ACTIVITY_SINGLE_TOP в том же намерении, то он будет завершен и воссоздан; для всех других режимов запуска или если задано FLAG_ACTIVITY_SINGLE_TOP, то это намерение будет доставлено в onNewIntent () текущего экземпляра.


Итак, либо
1 . Измените launchMode Действия A на что-то другое из стандартного (то есть. singleTask или что-то еще). Тогда ваш флаг FLAG_ACTIVITY_CLEAR_TOP не перезапустит вашу активность A.

или

2 . Используйте Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP в качестве вашего флага. Тогда это будет работать так, как вы хотите.

3 голосов
/ 05 декабря 2017

Я использую три флага для решения проблемы:

intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|
                Intent.FLAG_ACTIVITY_CLEAR_TASK | 
                Intent.FLAG_ACTIVITY_NEW_TASK);
2 голосов
/ 28 мая 2016

Добавить android: noHistory = "true" в файл манифеста.

<manifest >
        <activity
            android:name="UI"
            android:noHistory="true"/>

</manifest>
2 голосов
/ 16 мая 2014

Я знаю, что уже есть принятый ответ, но я не понимаю, как он работает для OP, потому что я не думаю, что FLAG_ACTIVITY_CLEAR_TOP имеет смысл в его конкретном случае. Этот флаг имеет отношение только к действиям в той же задаче . Исходя из его описания, каждое действие выполняет в своей задаче : A, B и браузер.

Что-то, что может его оттолкнуть, это то, что A - это однократная, тогда как это должна быть однократная задача. Если A - singleTop, и B запускает A, то будет создан новый A, потому что A не находится в задаче B. Из документации для singleTop:

"Если экземпляр действия уже существует в начале текущей задачи , система направляет намерение этому экземпляру ..."

Поскольку B запускает A, текущая задача является задачей B, которая предназначена для единственного экземпляра и, следовательно, не может включать A. Используйте singleTask для достижения желаемого результата, потому что тогда система найдет задачу, которая имеет A, и переведет эту задачу в передний план.

Наконец, после того, как B запустил A, и пользователь нажал назад от A, OP не хочет видеть ни B, ни браузер. Для этого вызов метода finish () в B верен; Опять же, FLAG_ACTIVITY_CLEAR_TOP не удалит другие действия в задаче А, потому что все остальные его действия находятся в разных заданиях. Часть, которую он пропустил, хотя это то, что B должен также использовать FLAG_ACTIVITY_NO_HISTORY при запуске намерения для браузера. Примечание: если браузер уже запущен еще до запуска приложения OP, то, конечно, вы увидите браузер при нажатии назад из A. Так что, чтобы действительно проверить это, обязательно выйдите из браузера перед запуском приложения.

1 голос
/ 31 октября 2014

я позвонил activity_name.this.finish() после начала нового намерения, и это сработало для меня.

I tried "FLAG_ACTIVITY_CLEAR_TOP" and "FLAG_ACTIVITY_NEW_TASK"

Но это не сработает для меня ... Я не предлагаю это решение для использования, но если установить флагне будет работать для вас, чем вы можете попробовать это .. Но все же я рекомендую не использовать его

1 голос
/ 25 июня 2011

Изначально у меня также были проблемы с работой FLAG_ACTIVITY_CLEAR_TOP.В конце концов я получил его на работу, используя его значение (0x04000000).Похоже, есть проблема с Eclipse / компилятором.Но, к сожалению, выживающая активность возобновляется, а это не то, чего я хочу.Похоже, что нет простого решения.

1 голос
/ 03 декабря 2010

FLAG_ACTIVITY_NEW_TASK - это проблема, которая инициирует новую задачу. Просто удалите ее, и все готово.

Хорошо, я рекомендую вам прочитать, что делает каждый Флаг, прежде чем работать с ними

Читать это & Флажки намерений здесь

...