Terminer une activité à partir d'une autre activité

101

Je souhaite terminer une activité à partir d'une autre activité, comme:

Dans l'activité [A], en cliquant sur le bouton, j'appelle l'activité [B] sans terminer l'activité [A].

Maintenant, dans l'activité [B], il y a deux boutons, Nouveau et Modifier . Lorsque l'utilisateur clique sur modifier puis pop une activité [A] de la pile avec toutes les options cochées.

Mais quand l'utilisateur clique sur le bouton Nouveau de l'activité [B], alors je devrai terminer l'activité [A] de la pile et recharger cette activité [A] à nouveau dans la pile.

J'essaye, mais je ne parviens pas à terminer l'activité [A] de la pile ... Comment puis-je le faire?

J'utilise le code comme:

De l'activité [A]:

Intent GotoB = new Intent(A.this,B.class);
startActivityForResult(GotoB,1);

Une autre méthode dans la même activité

public void onActivityResult(int requestCode, int resultCode, Intent intent) {

    if (requestCode == 1)
    {
        if (resultCode == 1) {
            Intent i = getIntent();
            overridePendingTransition(0, 0);
            i.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
            finish();

            overridePendingTransition(0, 0);
            startActivity(i);
        }
    }
}

Et dans l'activité [B], cliquez sur le bouton:

setResult(1);
finish();
Kanika
la source
hé, tu voulais finir une activité d'une autre droite ... alors j'avais posté la réponse qui est correcte. Mais pourquoi l'avez-vous rejetée?
Manjunath
Il y a un fil avec quelques belles réponses ici: stackoverflow.com/questions/14355731/...
ab

Réponses:

189
  1. Faites votre activité A dans le fichier manifeste: launchMode = "singleInstance"

  2. Lorsque l'utilisateur clique sur nouveau, faites FirstActivity.fa.finish();et appelez la nouvelle intention.

  3. Lorsque l'utilisateur clique sur Modifier, appelez la nouvelle intention ou terminez simplement l'activité B.

PREMIÈRE FAÇON

Dans votre première activité, déclarez-en une Activity objectcomme celle-ci,

public static Activity fa;
onCreate()
{
    fa = this;
}

utilisez maintenant cet objet dans un autre Activitypour terminer la première activité comme celle-ci,

onCreate()
{
    FirstActivity.fa.finish();
}

DEUXIÈME VOIE

Lorsque vous appelez votre activité FirstActivityque vous souhaitez terminer dès que vous passez, vous pouvez ajouter un indicateur lors de l'appelFirstActivity

intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);

Mais en utilisant cet indicateur, l'activité sera terminée même si vous ne le souhaitez pas. et parfois, onBacksi vous voulez montrer le, FirstActivityvous devrez l'appeler en utilisant l'intention.

MKJParekh
la source
6
Très bonne réponse..!!
Vaibhav Vajani
93
Vous détenez une référence statique à une activité. Cela ne disparaîtra jamais à moins que vous ne le supprimiez manuellement de quelque part -> vous créez une fuite de mémoire!
DArkO
5
Eh bien, c'est ok, vous avez mon +1 pour penser hors de la boîte: D, je voudrais simplement passer à singleTop. Cependant, ce ne sera toujours pas mon premier choix lorsque je fais quelque chose de similaire. par code de nettoyage, je voulais dire un moyen de se débarrasser de la référence statique afin qu'il n'y ait pas de fuite de mémoire, mais cela dépend de la structure de l'application.
DArkO
6
S'il vous plaît, personne n'utilise la première solution, c'est complètement faux. Vous contournez le framework Android de manière vraiment piratée tout en créant un objet zombie. Utilisez un BroadcastReceiver.
S-K '18
1
Des solutions géniales. A très bien fonctionné pour mon problème dans lequel je passais des activités A-> B-> C et sur onBackPressed de C, je lançais une nouvelle instance de B.Mais si je faisais onBackPressed sur cette nouvelle instance de B, il allez à l'ancienne instance de B au lieu de l'ancienne instance de A (ce que je voulais). J'ai donc suivi votre première méthode dans le onBackPressed de C, et cela m'a donné le comportement que je voulais :) Merci beaucoup :)
SoulRayder
87

Vous pouvez le faire, mais je pense que vous ne devriez pas briser le flux normal de l'activité. Si vous souhaitez terminer votre activité, vous pouvez simplement envoyer une diffusion de votre activité B vers l'activité A.

Créez un récepteur de diffusion avant de démarrer votre activité B:

BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {

    @Override
    public void onReceive(Context arg0, Intent intent) {
        String action = intent.getAction();
        if (action.equals("finish_activity")) {
            finish();
            // DO WHATEVER YOU WANT.
        }
    }
};
registerReceiver(broadcastReceiver, new IntentFilter("finish_activity"));

Envoyez la diffusion de l'activité B à l'activité A lorsque vous souhaitez terminer l'activité A à partir de B

Intent intent = new Intent("finish_activity");
sendBroadcast(intent);

J'espère que cela fonctionnera pour vous ...

Bharat Sharma
la source
Il affiche cette erreur "Erreur de syntaxe sur les jetons, AnnotationName attendue à la place" sur "registerReceiver (broadcast_reciever, new IntentFilter (" finish_activity "));". Qu'est-ce qui ne va pas?
Behzad
2
"vous ne devriez pas briser le flux normal de l'activité" +1 pour cela
S-K '18
11
N'oubliez pas de vous broadcast_receiverunregisterReceiver()
désinscrire
Telle est la solution. nice one
Parinda Rajapaksha
17

C'est une question de communication assez standard. Une approche serait d'utiliser un ResultReceiver dans l'activité A:

Intent GotoB=new Intent(A.this,B.class);
GotoB.putExtra("finisher", new ResultReceiver(null) {
    @Override
    protected void onReceiveResult(int resultCode, Bundle resultData) {
        A.this.finish();
    }
});
startActivityForResult(GotoB,1);

puis dans l'activité B, vous pouvez simplement le terminer à la demande comme ceci:

((ResultReceiver)getIntent().getExtra("finisher")).send(1, new Bundle());

Essayez quelque chose comme ça.

Femi
la source
6
+1 juste, ((ResultReceiver) getIntent (). GetParcelableExtra ("finisher")). Send (1, new Bundle ());
Hamidreza Sadegh
12

Il existe une approche que vous pouvez utiliser dans votre cas.

Étape 1: Démarrez l'activité B à partir de l'activité A

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

Étape 2: Si l'utilisateur clique sur le bouton Modifier, lancez l'activité A en utilisant le FLAG_ACTIVITY_CLEAR_TOP.Aussi, passez le drapeau en extra.

Intent i = new Intent(B.this, A.class);
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
i.putExtra("flag", "modify");
startActivity(i);
finish();

Étape 3: Si l'utilisateur clique sur le bouton Ajouter, lancez l'activité A en utilisant le FLAG_ACTIVITY_CLEAR_TOP.Also, passez l'indicateur en extra. FLAG_ACTIVITY_CLEAR_TOPeffacera toutes les activités ouvertes jusqu'à la cible et redémarrera si aucun mode de lancement n'est défini dans l'activité cible

Intent i = new Intent(B.this, A.class);
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
i.putExtra("flag", "add");
startActivity(i);
finish();

Étape 4: Maintenant, onCreate()méthode de l'activité A, vous devez récupérer cet indicateur.

String flag = getIntent().getStringExtra("flag");
if(flag.equals("add")) {
    //Write a code for add
}else {
    //Write a code for modifying
}
Dharmendra
la source
6

Démarrez votre activité avec le code de demande:

StartActivityForResult(intent,1234);

Et vous pouvez le fermer de toute autre activité comme celle-ci:

finishActivity(1234);
yaniv maymon
la source
Dans quelle langue??
Morten Holmgaard le
5

Voir ma réponse à la question de Stack Overflow Terminer Toutes les activités précédentes .

Ce dont vous avez besoin est d'ajouter le fichier Intent.FLAG_CLEAR_TOP. Cet indicateur garantit que toutes les activités au-dessus de l'activité ciblée dans la pile sont terminées et que celle-ci est affichée.

Une autre chose dont vous avez besoin est le SINGLE_TOPdrapeau. Avec celui-ci, vous empêchez Android de créer une nouvelle activité s'il y en a déjà une dans la pile.

Sachez simplement que si l'activité a déjà été créée, l'intention avec ces indicateurs sera fournie dans la méthode appelée onNewIntent(intent)(vous devez la surcharger pour la gérer) dans l'activité cible.

Ensuite, onNewIntentvous avez une méthode appelée redémarrage ou quelque chose qui appellera finish()et lancera une nouvelle intention vers lui-même, ou une repopulate()méthode qui définira les nouvelles données. Je préfère la deuxième approche, elle est moins chère et vous pouvez toujours extraire la onCreatelogique dans une méthode distincte que vous pouvez appeler pour peupler.

DArkO
la source
4

Je viens d'appliquer la solution de Nepster et fonctionne comme un charme. Il y a une modification mineure pour l'exécuter à partir d'un fragment.

À votre fragment

// sending intent to onNewIntent() of MainActivity
Intent intent = new Intent(getActivity(), MainActivity.class);
intent.putExtra("transparent_nav_changed", true);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);

Et à votre OnNewIntent () de l'activité que vous souhaitez redémarrer.

// recreate activity when transparent_nav was just changed
if (getIntent().getBooleanExtra("transparent_nav_changed", false)) {
    finish(); // finish and create a new Instance
    Intent restarter = new Intent(MainActivity.this, MainActivity.class);
    startActivity(restarter);
}
koras
la source
2

Je pense que j'ai l'approche la plus simple ... en appuyant sur nouveau dans B ..

Intent intent = new Intent(B.this, A.class);
intent.putExtra("NewClicked", true);
 intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);

et en A l'obtenir

  if (getIntent().getBooleanExtra("NewClicked", false)) {
        finish();// finish yourself and make a create a new Instance of yours.
      Intent intent = new Intent(A.this,A.class);
      startActivity(intent);
    }
AndroidGeek
la source
1

Je sais que c'est une vieille question, certaines de ces méthodes ne fonctionnaient pas pour moi, donc pour ceux qui cherchent dans l'avenir ou qui ont mes problèmes, cela a fonctionné pour moi

J'ai remplacé onPauseet appelé à l' finish()intérieur de cette méthode.

Tony Kutzler
la source
-1

Premier appel startactivity()puis utilisationfinish()

Dharmik Ghori
la source