Android: очистити стек активності


132

У мене є кілька заходів у моїй заявці. і потік дуже складний. Коли я натискаю програму виходу, переходить до екрана входу, а звідти користувач може вийти кнопкою скасування (дзвінок system.exit(0))

коли я виходжу або натискаю кнопку назад, система викликає активність із стека :( як я можу очистити всі дії в стеку, коли я дістанусь до екрана входу? виклик finish()не є практичним, оскільки існує так багато заходів, і деякі дії не повинні закриватися, коли вони активні, такі як націлювання на натиснуту камеру.

validateuser logoutuser = new validateuser();
logoutuser.logOut();
Intent loginscreen = new Intent(homepage.this, Login2.class);
(homepage.this).finish();
loginscreen.setFlags( Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(loginscreen);

1
перевірити це посилання ... stackoverflow.com/questions/5139686/exit-an-android-app / ...
xydev

Відповіді:


339

Більшість з вас помиляються. Якщо ви хочете закрити існуючий стек діяльності незалежно від того, що там є, і створити новий корінь, правильний набір прапорів наступний:

intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);

Від док .

public static final int FLAG_ACTIVITY_CLEAR_TASK
Додано в рівень 11 API

Якщо встановлено у намірі, переданому до Context.startActivity()цього, цей прапор призведе до очищення будь-якого існуючого завдання, яке було б пов’язане з діяльністю до початку діяльності. Тобто активність стає новим коренем інакше порожнього завдання, і будь-які старі дії закінчуються. Це можна використовувати лише спільно з FLAG_ACTIVITY_NEW_TASK.


Працювали чудово. Дякую. Як не дивно, помилка не була з minSDK = 9.
Mahm00d

Відверто кажучи, я ніколи не користувався цією функціональністю, воскрешав після аварії тощо, і скоріше зосередився на вирішенні проблем, які спричинили аварію)
Cynichniy Bandera

Таку ж функціональність забезпечує і IntentCompat.makeRestartActivityTaskбібліотека підтримки.
sealskej

Додавання лише цих двох прапорів залишає стек активності позаду (починається зверху попереднього), потім додається Намір.FLAG_ACTIVITY_CLEAR_TOP, який просто перезавантажує програму, а потім повністю завершує роботу. Я не додав жодного прапора до діяльності, явно тхо. У чому може бути проблема?
Фарид

1
Одне з найкращих початків: «Більшість із вас помиляються».
nibbana

31

Коли ви зателефонували startActivityна останню активність, ви завжди могли користуватися

Intent.FLAG_ACTIVITY_CLEAR_TOP

як прапор цього наміру.

Детальніше про прапор читайте тут .


це також не допомагає. Я просто підводить дату діяльності не закінчується закінченням (); :(
Джей Маю

Я думаю, що FLAG_ACTIVITY_CLEAR_TOP очищає діяльність у верхній частині. Моя проблема - це діяльність внизу :(
Jay Mayu

Я думаю, це залежить від того, яким потоком є ​​насправді. Більше про це слід прочитати тут: developer.android.com/reference/android/content/… та developer.android.com/guide/topics/fundamentals/…
Девід Олссон

7
Дякуємо, що показали правильні ресурси. помилка, яку я зробив, була закриття активності входу. Я не повинен її закривати. Коли активність завантажується першою. тому коли я передзвоню його за допомогою прапорця Clear_top, активність входу очищає всі дії вгорі. Оскільки логін є першим захопленням, він очищає всі дії, розпочаті після. так бинго це спрацювало :)
Jay Mayu

13
З документації FLAG_ACTIVITY_CLEAR_TOP очищає стек лише в тому випадку, якщо конкретна діяльність "вже виконується в поточному завданні"
AlikElzin-kilaka

16

Ось простий допоміжний метод для запуску нової діяльності, як нової основної діяльності, яка працює від API рівня 4 до поточної версії 17:

static void startNewMainActivity(Activity currentActivity, Class<? extends Activity> newTopActivityClass) {
    Intent intent = new Intent(currentActivity, newTopActivityClass);
    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
        intent.addFlags(0x8000); // equal to Intent.FLAG_ACTIVITY_CLEAR_TASK which is only available from API level 11
    currentActivity.startActivity(intent);
}

назвіть це так із вашої поточної діяльності:

startNewMainActivity(this, MainActivity.class);

1
Не могли б ви завжди завжди використовувати intent.addFlags (0x8000); і спростити це?
Давор

Оскільки цей прапор був вперше представлений у стільниковій сотці, я не маю уявлення, яке значення це може мати для попередніх версій. Отже, це я був передумов. Але я гадаю, що видалення кондиції не повинно бути проблемою.
хлюп

1
ви хочете додати цей прапор, коли рівень API <11, тоді вам потрібно зробити Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMBще intent.addFlags(0x8000);ніколи не буде додано
Straw Hat

Мені спонукає користувачів здійснювати багато заходів одна за одною через наміри. Чи потрібно мені щось робити, щоб переконатися, що програма не виходить з ладу із занадто великою кількістю дій на стеці? Дякую!
Ручір Баронія

9

Очистити заднім числом активності за вказаним нижче кодом:

Intent intent = new Intent(Your_Current_Activity.this, Your_Destination_Activity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK |Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);

Зроблено


Мені спонукає користувачів здійснювати багато заходів одна за одною через наміри. Чи потрібно мені щось робити, щоб переконатися, що програма не виходить з ладу із занадто великою кількістю дій на стеці? Дякую!
Ручір Баронія

@RuchirBaronia, якщо ви переходите до A -> B -> C -> D -> E -> F -> G -> H, тепер H -> Я ви пишете свій код, ніж я буду Останнім активом, після чого натискаєте кнопку Назад додаток закриється, оскільки у додатку немає активності в задньому плані.
Хірен Патель

Чи потрібно мені це робити? Що буде, якщо я ніколи не очищую стек від діяльності?
Ручір Баронія

@RuchirBaronia, Backpress: H -> G -> F -> E -> D -> C -> B -> A
Hiren Patel

Але деякий час він показує білий екран під час виклику нової активності. Хо вирішити це?
Сагар

4

У моєму випадку також було закрито LoginActivity. Як результат,

Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK

не допомогло.

Однак налаштування

Intent.FLAG_ACTIVITY_NEW_TASK

мені допомогли.


Мені спонукає користувачів здійснювати багато заходів одна за одною через наміри. Чи потрібно мені щось робити, щоб переконатися, що програма не виходить з ладу із занадто великою кількістю дій на стеці? Дякую!
Ручір Баронія

3
Intent intent = new Intent(LoginActivity.this, Home.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);  //It is use to finish current activity
startActivity(intent);
this.finish();

1
чому ви використовуєте і те, this.finish()і setFlags()також для очищення поточної активності?
Сагар

3

Я зазначив, що ви попросили рішення, на яке не покладаєтесь finish(), але мені цікаво, чи все-таки це може допомогти.

Я відстежував, чи піднімається прапор виходу зі змінною статичного класу, яка переживає весь термін служби додатка. Використовуйте кожну відповідну діяльністьonResume()

@Override
public void onResume() {
    super.onResume();
    if (ExitHelper.isExitFlagRaised) {
        this.finish();
    }
}

Клас ExitHelper

public class ExitHelper {
    public static boolean isExitFlagRaised = false;
}

Скажімо, в mainActivity користувач натискає кнопку для виходу - ви можете встановити ExitHelper.isExitFlagRaised = true;і потім finish(). Після цього будуть завершені й інші відповідні дії, які автоматично відновляються.


що станеться, якщо я використаю код у MainActivity onresume (), то повернусь до майна активності з другої активності onbackpress
Mithu,

3

Це рішення прекрасно працює:

intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);

Але нова активність запускається довго, і ви бачите білий екран деякий час. Якщо це критично, то скористайтеся цим способом вирішення:

public class BaseActivity extends AppCompatActivity {

    private static final String ACTION_FINISH = "action_finish";

    private BroadcastReceiver finisBroadcastReceiver;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        registerReceiver(finisBroadcastReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                finish();
            }
        }, new IntentFilter(ACTION_FINISH));
    }

    public void clearBackStack() {
        sendBroadcast(new Intent(ACTION_FINISH));
    }

    @Override
    protected void onDestroy() {
        unregisterReceiver(finisBroadcastReceiver);
        super.onDestroy();
    }
}

Як користуватися ним:

public class ActivityA extends BaseActivity {

    // Click any button
    public void startActivityB() {
        startActivity(new Intent(this, ActivityB.class));
        clearBackStack();
    }
}

Недолік: усі дії, які потрібно закрити в стеку, повинні поширювати BaseActivity



1

Використання Котліна:

Ви можете встановити прапор безпосередньо, використовуючи метод сеттера. У Котліні orє заміна Java побіжно або |.

intent.flags = FLAG_ACTIVITY_NEW_TASK or FLAG_ACTIVITY_CLEAR_TASK

Якщо ви плануєте регулярно використовувати це, створіть функцію розширення намірів

fun Intent.clearStack() {
    flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
}

Потім ви можете безпосередньо зателефонувати до цієї функції перед запуском наміру

intent.clearStack()
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.