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



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



ситуация



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



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



Примечания



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

606   10  

10 ответов:

в API level 11 был добавлен новый флаг намерения именно для этого:намерениях.FLAG_ACTIVITY_CLEAR_TASK

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

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

к сожалению для API lvl "DontHackAndroidLikeThis" решение это действительно чистый хакерство. Вы не должны этого делать. :)

Edit: Согласно @Бен Пирсон's комментарий, для API IntentCompat класс для того же. Можно использовать IntentCompat.FLAG_ACTIVITY_CLEAR_TASK флаг для очистки задачи. Таким образом, вы также можете поддерживать pre API level 11.

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

здесь поток активности-это A - >B .При нажатии кнопки "назад" из B нам нужно закрыть приложение, а затем при запуске Activity B с помощью just call finish() это предотвратит сохранение Android активности A в Backstack.eg для активности A-это размещение / заставка приложения.

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

случай 2: более двух видов деятельности:

Если есть поток, как A - >B - >C - >D - >B и on нажав кнопку "Назад" в деятельности B, а поступающие от деятельности Д. В этом случае мы должны использовать.

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 будет запущено из backstack, а не из нового экземпляра из-за намерения.FLAG_ACTIVITY_CLEAR_TOP и намерение.FLAG_ACTIVITY_NEW_TASK очищает стек и делает его верхним one.So когда мы нажимаем кнопку назад, все приложение будет прекращено.

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

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

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

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

Что делать? Поместите запускаемое действие в стек с помощью FLAG_ACTIVITY_NEW_TASK, что делает это действие началом новой задачи в стеке истории. Затем добавьте флаг FLAG_ACTIVITY_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 back должна работать как в веб-браузере.

Я могу придумать способ сделать это, но это довольно рубить.

  • Сделайте свою деятельность 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);

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

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

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

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

Comments

    Ничего не найдено.