Android: очистить стек активности - PullRequest
113 голосов
/ 16 августа 2011

У меня есть несколько действий в моем приложении. и поток очень сложный. Когда я нажимаю на кнопку «Выйти», открывается окно входа в систему, и пользователь может выйти с помощью кнопки отмены (вызов system.exit(0))

когда я выхожу или нажимаю кнопку "назад", система вызывает действие из стека :( как я могу очистить все действия в стеке, когда я попадаю на экран входа в систему? не должны закрываться, когда они активны, например, при вызове собственной камеры.

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);

Ответы [ 9 ]

302 голосов
/ 06 мая 2013

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

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

Из документа :

public static final int FLAG_ACTIVITY_CLEAR_TASK
Добавлен на уровне API 11

Если задано значение Intent, переданное в Context.startActivity(), этот флаг вызовет очистку любой существующей задачи, которая будет связана с действием, додеятельность началась.Таким образом, действие становится новым корнем в противном случае пустой задачи, и все старые действия завершаются.Это можно использовать только в сочетании с FLAG_ACTIVITY_NEW_TASK.

29 голосов
/ 16 августа 2011

Когда вы звоните startActivity на последнем занятии, вы всегда можете использовать

Intent.FLAG_ACTIVITY_CLEAR_TOP

как флаг для этого намерения.

Подробнее о флаге здесь .

16 голосов
/ 22 мая 2013

Вот простой вспомогательный метод для запуска нового действия в качестве нового главного действия, который работает с уровня 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);
6 голосов
/ 21 июня 2015

Очистить активность Backstate по нижеследующему коду:

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);

Выполнено

4 голосов
/ 21 декабря 2012

В моем случае, LoginActivity также было закрыто.В результате

Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK

не помогло.

Однако настройка

Intent.FLAG_ACTIVITY_NEW_TASK

помогла мне.

3 голосов
/ 27 августа 2017

Это решение отлично работает:

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

3 голосов
/ 09 октября 2015
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();
2 голосов
/ 03 февраля 2016

Я заметил, что вы просили решение, не основанное на 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().После этого другие соответствующие действия, которые возобновляются автоматически, также будут завершены.

1 голос
/ 28 декабря 2017

Для разработчиков Xamarin вы можете использовать:

intent.SetFlags(ActivityFlags.NewTask | ActivityFlags.ClearTask);
...