Удаление активности из стека истории

Мое приложение показывает активность регистрации в первый раз, когда пользователь запускает приложение, выглядит так:

  1. ActivitySplashScreen (добро пожаловать в игру, зарегистрировать аккаунт?)
  2. ActivitySplashScreenSignUp (отлично, заполните эту информацию)
  3. ActivityGameMain (основной экран игры)

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

Когда пользователь переходит от действия № 2 к № 3, возможно ли полностью стереть № 1 и № 2 из стека истории? Мне бы хотелось, чтобы, если пользователь находится на #3 и нажимает кнопку "Назад", он просто переходил на домашний экран, а не обратно на заставку.

Я думаю, что я могу сделать это с помощью задач (т.е. начать новую задачу на #3), но хотел посмотреть, есть ли более простой метод,

Спасибо

17 ответов

Вы можете достичь этого, установив android:noHistory приписать "true" в соответствующем <activity> записи в вашем AndroidManifest.xml файл. Например:

<activity
    android:name=".AnyActivity"
    android:noHistory="true" />

Вы можете использовать переадресацию, чтобы удалить предыдущее действие из стека действий при запуске следующего. В APIDemos есть пример этого, но в основном все, что вы делаете, это звонит finish() сразу после звонка startActivity(),

Да, взгляните на Intent.FLAG_ACTIVITY_NO_HISTORY.

Это, вероятно, не идеальный способ сделать это. Если у кого-то есть лучший способ, я буду с нетерпением ждать его реализации. Вот как я выполнил эту конкретную задачу с SDK до версии 11.

в каждом классе вы хотите уйти, когда наступит ясное время, вам нужно сделать это:

    ... interesting code stuff ...
    Intent i = new Intent(MyActivityThatNeedsToGo.this, NextActivity.class);
    startActivityForResult(i, 0);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (resultCode == R.string.unwind_stack_result_id) {
        this.setResult(R.string.unwind_stack_result_id);
        this.finish();
    }
}

тогда тот, который должен отключить цепочку всплывающих окон из стека, должен просто вызвать его, когда вы хотите его инициировать:

NextActivity.this.setResult(R.string.unwind_stack_result_id);
NextActivity.this.finish();

Тогда действия не в стеке!
Помните, ребята, что вы можете начать действие, а затем начать убирать за ним, выполнение не следует ни за одним (пользовательским) потоком.

Один из способов, который работает до API 11, - это запустить ActivityGameMain сначала в onCreate этой деятельности начать свой ActivitySplashScreen деятельность. ActivityGameMain не появится, так как вы вызываете startActivity слишком рано для всплеска.

Затем вы можете очистить стек при запуске ActivityGameMain установив эти флаги в Intent:

intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);

Вы также должны добавить это в ActivitySplashScreen:

@Override
public void onBackPressed() {
    moveTaskToBack(true);
}

Таким образом, если вы продолжите нажимать на эту активность, это не приведет к ActivityGameMain,

Я полагаю, что вы не хотите, чтобы экран-заставка возвращался обратно, для достижения этого я предлагаю установить его на noHistory в вашем AndroidManifest.xml, Затем положить goBackPressed код в вашем ActivitySplashScreenSignUp класс вместо.

Однако я нашел несколько способов сломать это. Запустите другое приложение из уведомления, пока ActivitySplashScreenSignUp отображается, и история изменений не сбрасывается.

Единственный реальный способ обойти это в API 11:

intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);

Я использую этот способ.

Intent i = new Intent(MyOldActivity.this, MyNewActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK)
startActivity(i);

В манифест вы можете добавить:

android:noHistory="true"

<activity
android:name=".ActivityName"
android:noHistory="true" />

Вы также можете позвонить

finish()

сразу после вызова startActivity(..)

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

//We want the home screen to behave like the bottom of the activity stack so we do not return to the initial screen
//unless the application has been killed. Users can toggle the session mode with a menu item at all other times.
@Override
public void onBackPressed() {
    //Check the activity stack and see if it's more than two deep (initial screen and home screen)
    //If it's more than two deep, then let the app proccess the press
    ActivityManager am = (ActivityManager)this.getSystemService(Activity.ACTIVITY_SERVICE);
    List<RunningTaskInfo> tasks = am.getRunningTasks(3); //3 because we have to give it something. This is an arbitrary number
    int activityCount = tasks.get(0).numActivities;

    if (activityCount < 3)
    {
        moveTaskToBack(true);
    }
    else
    {
        super.onBackPressed();
    }
}

Просто установите noHistory="true" в файле манифеста. Это делает деятельность удаляемой из backstack.

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

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

Из документов Android:

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

If set in an Intent passed to Context.startActivity(), this flag will cause any existing task that would be associated with the

активность должна быть очищена до начала действия. Таким образом, действие становится новым корнем в противном случае пустой задачи, и все старые действия завершаются. Это можно использовать только в сочетании с FLAG_ACTIVITY_NEW_TASK.

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

SplashActivity -> AuthActivity -> DashActivity

if (!sessionManager.isLoggedIn()) {
    Intent intent = new Intent(context, AuthActivity.class);
    intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
    context.startActivity(intent);
    finish();
} else {
   Intent intent = new Intent(context, DashActivity.class);
   context.startActivity(intent);
    finish();
}

Ключ здесь заключается в использовании intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY); для посредника Activity, Как только эта средняя ссылка разорвана, DashActivity будет первым и последним в стеке.

android:noHistory="true" это плохое решение, так как оно вызывает проблемы, когда полагается на Activity в качестве обратного вызова, например onActivityResult, Это рекомендуемое решение и должно быть принято.

Для API >= 15 к API 23 другое решение не работает в моем случае. наконец я понял это.

 Intent nextScreen = new Intent(currentActivity.this, MainActivity.class);
 nextScreen.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | IntentCompat.FLAG_ACTIVITY_CLEAR_TASK);
 startActivity(nextScreen);
 ActivityCompat.finishAffinity(currentActivity.this);

Просто вызовите this.finish() перед startActivity(намерением) следующим образом:

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

Удаление активности из истории осуществляется путем установки флага перед действием, которое вам не нужно.

А-> Б->C->D

Предположим, что A,B,C и D - это 4 действия, если вы хотите очистить B и C, затем установите флаг

intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);

В деятельности A и B

Вот бит кода

Intent intent = new Intent(this,Activity_B.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(intent);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            super.finishAndRemoveTask();
        }
        else {
            super.finish();
        }

Здесь я перечислил несколько способов выполнить эту задачу:

  1. Перейдите в файл manifest.xml и укажите android:noHistory="true", чтобы удалить активность из стека.

  2. При переключении с текущего действия на какое-либо другое действие в намерении установите флаг как (Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK). Это продемонстрировано на примере ниже.

    Намерение намерение = новое намерение (CurrentActivity.this, HomeActivity.class); намерение.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |Intent.FLAG_ACTIVITY_CLEAR_TASK)startActivity(намерение);здесь

Примечание . Установка флагов намерения может привести к тому, что экран будет пустым на какое-то время (при переключении активности).

Попробуй это:

intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY)

это API Уровень 1, проверьте ссылку.

Другие вопросы по тегам