При выходе из системы очистите стек истории действий, чтобы кнопка «Назад» не открывала вход в систему только для входа. - PullRequest
225 голосов
/ 09 июня 2010

Все действия в моем приложении требуют, чтобы пользователь был авторизован для просмотра.Пользователи могут выйти практически из любой активности.Это требование приложения.В любой момент, если пользователь выходит из системы, я хочу отправить пользователя на логин Activity.На данный момент я хочу, чтобы это действие было в нижней части стека истории, чтобы при нажатии кнопки «назад» пользователь возвращался на домашний экран Android.

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

Я попытался открыть действие входа в систему, установив для его флагов Intent значение FLAG_ACTIVITY_CLEAR_TOP, что выглядитсделать, как указано в документации, но не достиг своей цели - поместить действие «Вход в систему» ​​внизу стека истории и не дать пользователю перейти обратно к ранее просмотренным действиям, вошедшим в систему.Я также попытался использовать android:launchMode="singleTop" для входа в систему в манифесте, но это также не решает мою задачу (и, похоже, не дает никакого эффекта).

Мне кажется, мне нужно либо очистить стек истории,или завершите все ранее открытые действия.

Один из вариантов - иметь для каждого действия onCreate проверку статуса входа в систему и finish(), если не вошел в систему.Мне не нравится эта опция, поскольку кнопка «Назад» будет по-прежнему доступна для использования, переходя назад, когда действия закрываются.

Следующий вариант - сохранить LinkedList ссылок на все открытые действия, которые являются статически.доступны везде (возможно, с использованием слабых ссылок).Выйдя из системы, я получу доступ к этому списку и переберу все ранее открытые действия, вызывая finish() для каждого из них.Я, вероятно, скоро начну реализовывать этот метод.

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

Есть ли способ сделать это с помощью Intent илинастройки манифеста, или мой второй вариант, поддержание LinkedList открытых действий - лучший вариант?Или есть другой вариант, который я полностью пропускаю?

Ответы [ 18 ]

1 голос
/ 31 августа 2017

Иногда finish() не работает

Я решил эту проблему с

finishAffinity()

1 голос
/ 12 февраля 2018

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

@Override
public void onBackPressed() {
    // disable going back to the MainActivity
    moveTaskToBack(true);
}

Я предполагаю, что LoginActivity завершается сразу после входа пользователя в систему, поэтому он не может вернуться к нему позже, нажав кнопку «Назад». Вместо этого пользователь должен нажать кнопку выхода из приложения внутри приложения, чтобы правильно выйти из системы. Эта кнопка выхода из системы реализует простое намерение:

Intent intent = new Intent(this, LoginActivity.class);
startActivity(intent);
finish();

Все предложения приветствуются.

0 голосов
/ 24 июня 2015

Это сработало для меня:

     // After logout redirect user to Loing Activity
    Intent i = new Intent(_context, MainActivity.class);
    // Closing all the Activities
    i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);

    // Add new Flag to start new Activity
    i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

    // Staring Login Activity
    _context.startActivity(i);
0 голосов
/ 31 июля 2014

Это возможно, управляя флагом в SharedPreferences или в Application Activity.

При запуске приложения (на заставке) установите флаг = false;При событии «Выйти из системы» просто установите флаг «true» и в OnResume () каждого действия проверьте, установлен ли флаг «true», затем вызовите finish ().

Это работает как шарм :)

0 голосов
/ 23 февраля 2012

при выходе из системы вы можете назвать это

private void GoToPreviousActivity() {
    setResult(REQUEST_CODE_LOGOUT);
    this.finish();
}

onActivityResult () предыдущей операции, вызывайте этот код еще раз, пока вы не завершите все действия.

0 голосов
/ 15 декабря 2010

Начните свою деятельность с StartActivityForResult, и пока вы выходите из системы, установите свой результат и, в соответствии с вашим результатом, завершите свою деятельность

intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivityForResult(intent, BACK_SCREEN);

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    switch (requestCode) {
    case BACK_SCREEN:
        if (resultCode == REFRESH) {
            setResult(REFRESH);
            finish();
        }
        break;
    }
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_BACK) {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        AlertDialog alertDialog = builder.create();

        alertDialog
                .setTitle((String) getResources().getText(R.string.home));
        alertDialog.setMessage((String) getResources().getText(
                R.string.gotoHome));
        alertDialog.setButton(DialogInterface.BUTTON_POSITIVE, "Yes",
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog,
                            int whichButton) {

                        setResult(REFRESH);
                        finish();
                    }

                });

        alertDialog.setButton(DialogInterface.BUTTON_NEGATIVE, "No",
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog,
                            int whichButton) {
                    }
                });
        alertDialog.show();
        return true;
    } else
        return super.onKeyDown(keyCode, event);

}
0 голосов
/ 20 июня 2014

Решение @doreamon отлично работает во всех случаях, кроме одного:

Если после входа в систему пользователь Killing Login перешел прямо к среднему экрану. например В потоке A-> B-> C, перейдите как: Логин -> B -> C -> Нажмите ярлык для дома. Использование FLAG_ACTIVITY_CLEAR_TOP очищает только действие C, так как Home (A) отсутствует в истории стека. Нажатие Назад на экране приведет нас обратно к B.

Чтобы решить эту проблему, мы можем сохранить стек действий (Arraylist), а когда нажата кнопка home, мы должны убить все действия в этом стеке.

0 голосов
/ 09 июня 2010

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

То, что вы хотите сделать, это вызвать logout () и finish () на вашемМетоды onStop () или onPause ().Это заставит Android вызывать onCreate () при возобновлении активности, поскольку он больше не будет находиться в стеке своей активности.Затем сделайте, как вы говорите, в onCreate () проверьте статус входа в систему и перешли на экран входа в систему, если не вошли в систему.

Еще одна вещь, которую вы можете сделать, это проверить статус входа в систему в onResume (), и если вы не вошли, finish () и запуск активности входа в систему.

...