Очистить всю историю стека и начните новую активность на Android

StackOverflow https://stackoverflow.com/questions/3473168

Вопрос

Можно ли начать активность на стеке, очистить всю историю перед ней?

Ситуация

У меня есть стек деятельности, который либо идет A-> B-> C или B-> C (экран A Выбирает токен пользователя, но у многих пользователей есть только один токен).

На экране C пользователь мая Возьмите действие, которое делает экран B недействительным, поэтому приложение хочет взять их на экран A, независимо от того, уже находится в стеке. Экран A должен быть единственным элементом на стеке в моем приложении.

Примечания

Есть много других подобных вопросов, но я не нашел ничего, что отвечает на этот точный вопрос. Я пытался позвонить getParent().finish() - Это всегда приводит к нулевым указательным исключением. FLAG_ACTIVITY_CLEAR_TOP работает только, если активность уже находится в стеке.

Это было полезно?

Решение

На уровне API был добавлен новый флаг намерения был добавлен только для этого: Intent.flag_activity_clear_task.

Просто чтобы уточнить, используйте это:

Джава

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


Котлин

intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK


К сожалению для API LVL <= 10, я еще не нашел чистое решение этого. То РЕШЕНИЕ "DONTHACCANDIRDLIKETHIS" действительно чистый буксир. Вы не должны этого делать. :)

Редактировать:Согласно @Бен Пирсонкомментарий, для API <= 10 теперь можно использовать Intentcompat. класс для того же. Можно использовать IntentCompat.FLAG_ACTIVITY_CLEAR_TASK Флаг для очистки задачи. Таким образом, вы также можете поддерживать Pre API уровня 11 также.

Другие советы

Случай 1: только два активности A и B:

Вот поток активности - это> б. Проживание / всплеск экрана приложения.

Intent newIntent = new Intent(A.this, B.class);
startActivity(newIntent);
finish();

Случай 2: более двух активтов:

Если есть поток, такой как A-> B-> C-> D-> B и нажав кнопку «Назад» в действии B при выходе из активности D. В этом случае мы должны использовать.

Intent newIntent = new Intent(D.this,B.class);
newIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(newIntent);

Вот активность B будет запущена с точки блокировки, а не нового экземпляра из-за намерения .flag_activity_clear_top и intent.flag_activity_new_task Очищает стек и делает его верхним числом. Так как мы нажимаем кнопку назад, все приложение будет прекращено.

С новой версией Android> = API 16 finishAffinity()

Подход подходит для> = API 16.

Intent mIntent = new Intent(mContext,MainActivity.class);
finishAffinity();
startActivity(mIntent);
  • Это такое же, как и стартовая новая активность, и очистить весь стек.
  • Или перезапустить до местуактивности / первой активности.

Я тоже потратил несколько часов ... и согласен с тем, что flag_activity_clear_top звучит как то, что вы хотите: очистить весь стек, за исключением запуска активности, поэтому кнопка назад выходит на приложение. Тем не менее, как упомянуто Майк Реклам, флаг_Кактивность_clear_top работает только при запуске деятельности, уже в стеке; Когда активность не там, флаг ничего не делает.

Что делать? Поместите активность запуска в стеке с Flag_activity_new_Task, что делает эту деятельность на начало новой задачи в стеке истории. Затем добавьте флаг «Флаг_ »_Clear_top.

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

Вот моя функция выхода из системы; Параметр View - это кнопка, к которой прилагается функция.

public void onLogoutClick(final View view) {
    Intent i = new Intent(this, Splash.class);
    i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
    startActivity(i);
    finish();
}

Вы не должны менять стек. Кнопка «Android» должна работать в веб-браузере.

Я могу думать о том, как это сделать, но это довольно взломать.

  • Сделать свою деятельность singleTask добавив его в AndroidManifestПример:

    <activity android:name=".activities.A"
              android:label="@string/A_title"
              android:launchMode="singleTask"/>
    
    <activity android:name=".activities.B"
              android:label="@string/B_title"
              android:launchMode="singleTask"/>
    
  • Продлевать Application который будет держать логику куда идти.

Пример:

public class DontHackAndroidLikeThis extends Application {

  private Stack<Activity> classes = new Stack<Activity>();

  public Activity getBackActivity() {
    return classes.pop();
  }

  public void addBackActivity(Activity activity) {
    classes.push(activity);
  }
}

От а до б:

DontHackAndroidLikeThis app = (DontHackAndroidLikeThis) getApplication();
app.addBackActivity(A.class); 
startActivity(this, B.class);

От b до c:

DontHackAndroidLikeThis app = (DontHackAndroidLikeThis) getApplication();
app.addBackActivity(B.class); 
startActivity(this, C.class);

В C:

If ( shouldNotGoBackToB() ) {
  DontHackAndroidLikeThis app = (DontHackAndroidLikeThis) getApplication();
  app.pop();
}

и обрабатывать кнопку задней pop() из стека.

Еще раз, вы не должны делать это :)

Сразу после начнете новую активность, используя startActivity, убедитесь, что вы звоните finish() так что текущая активность не сложена за новым.

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

Intent logout_intent = new Intent(DashboardActivity.this, LoginActivity.class);
logout_intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
logout_intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
logout_intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(logout_intent);
finish();
Intent i = new Intent(MainPoliticalLogin.this, MainActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(i);

Попробуйте ниже код,

Intent intent = new Intent(ManageProfileActivity.this, LoginActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|
                Intent.FLAG_ACTIVITY_CLEAR_TASK| 
                Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);

Для меня никто из вышеперечисленных методов не работа.

Просто сделай это, чтобы Очистить все предыдущие действия:

finishAffinity() // if you are in fragment use activity.finishAffinity()
Intent intent = new Intent(this, DestActivity.class); // with all flags you want
startActivity(intent)

Я нашел слишком простой взлом, просто сделай это добавить новый элемент в AndroidManifest так как:-

<activity android:name=".activityName"
          android:label="@string/app_name"
          android:noHistory="true"/>

то android:noHistory очистит вашу нежелательную активность от стека.

Иногда ваш эмулятор Android может не подключить инструмент Eclipse DDMS и попросить ADB начать вручную. В этом случае вы можете начать или остановить ADB с помощью командной строки.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top