web-dev-qa-db-fra.com

Android: Clear Activity Stack

J'ai plusieurs activités dans mon application. et le flux est très compliqué. Lorsque je clique sur l'application Déconnexion, les navigateurs se connectent à l'écran de connexion et, à partir de là, l'utilisateur peut quitter en annulant le bouton (appeler system.exit(0)).

quand je sors ou retourne, le système appelle une activité de la pile :( comment puis-je effacer toutes les activités de la pile quand j'atteins l'écran de connexion? appeler finish() n'est pas pratique car il y a tellement d'activités et certaines les activités ne doivent pas être fermées lorsqu'elles sont actives, telles que l'activité d'appel de caméra native.

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);
119
Jay Mayu

La plupart d'entre vous ont tort. Si vous souhaitez fermer la pile d'activités existante indépendamment de ce qu'il y a dedans et créer une nouvelle racine, le jeu correct d'indicateurs est le suivant:

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

de la doc :

public static final int FLAG_ACTIVITY_CLEAR_TASK
Ajouté à l'API niveau 11

S'il est défini dans une intention transmise à Context.startActivity(), cet indicateur effacera toute tâche existante qui serait associée à l'activité avant son démarrage. En d’autres termes, l’activité devient la nouvelle racine d’une tâche par ailleurs vide et toutes les anciennes activités sont terminées. Ceci ne peut être utilisé qu'avec FLAG_ACTIVITY_NEW_TASK.

307

Lorsque vous appelez startActivity lors de la dernière activité, vous pouvez toujours utiliser

Intent.FLAG_ACTIVITY_CLEAR_TOP

comme un drapeau sur cette intention.

En savoir plus sur le drapeau ici .

29
David Olsson

Voici une méthode d'assistance simple pour démarrer une nouvelle activité en tant que nouvelle activité principale, qui fonctionne à partir du niveau 4 de l'API jusqu'à la version 17 actuelle:

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

appelez ça comme ça depuis votre activité actuelle:

startNewMainActivity(this, MainActivity.class);
16
whlk

Clear Activity Backstate par le code ci-dessous:

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

Fait

7
Hiren Patel

Dans mon cas, LoginActivity était également fermé. Par conséquent,

Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK

n'a pas aidé.

Cependant, la mise

Intent.FLAG_ACTIVITY_NEW_TASK

m'a aidé.

4
Prashant Gami
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();
3
Sakib Syed

Cette décision fonctionne bien:

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

Mais la nouvelle activité démarre longtemps et vous voyez un écran blanc un certain temps. Si cela est critique, utilisez cette solution de contournement:

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

Comment l'utiliser:

public class ActivityA extends BaseActivity {

    // Click any button
    public void startActivityB() {
        startActivity(new Intent(this, ActivityB.class));
        clearBackStack();
    }
}

Inconvénient: toutes les activités qui doivent être fermées sur la pile doivent étendre BaseActivity.

3
maXp

J'ai remarqué que vous aviez demandé une solution qui ne repose pas sur finish(), mais je me demande si cela peut néanmoins vous aider.

J'ai suivi si un indicateur de sortie est levé avec une variable de classe statique, qui survit à la durée de vie de l'application. Dans chaque pertinent de l'activité onResume(), utilisez

@Override
public void onResume() {
    super.onResume();
    if (ExitHelper.isExitFlagRaised) {
        this.finish();
    }
}

La classe ExitHelper

public class ExitHelper {
    public static boolean isExitFlagRaised = false;
}

Supposons que, dans mainActivity, un utilisateur appuie sur un bouton pour quitter. Vous pouvez définir ExitHelper.isExitFlagRaised = true; Puis finish(). Par la suite, les autres activités pertinentes qui sont automatiquement reprises seront également terminées.

2
Kevin Lee

Pour les développeurs Xamarin, vous pouvez utiliser:

intent.SetFlags(ActivityFlags.NewTask | ActivityFlags.ClearTask);
1
BYISHIMO Audace