web-dev-qa-db-fra.com

Fermez l'application et lancez l'écran d'accueil sur Android

J'ai deux activités différentes. Le premier lance le second. Dans la deuxième activité, j'appelle System.exit(0) afin de forcer la fermeture de l'application, mais la première activité est automatiquement affichée à la place du retour de l'application à l'écran d'accueil. Comment puis-je éviter cela et faire en sorte que l'application revienne à l'écran d'accueil?

75
Arutha

Vous devriez vraiment penser à ne pas quitter l'application. Ce n'est pas comme cela que les Android applications fonctionnent habituellement.

45
Romain Guy

Réponse courte: appelez moveTaskToBack(true) sur votre Activity au lieu de System.exit(). Cela masquera votre application jusqu'à ce que l'utilisateur souhaite l'utiliser à nouveau.

La réponse la plus longue commence par une autre question: pourquoi voulez-vous tuer votre application?

Le système d'exploitation Android gère la gestion de la mémoire et les processus, etc.), de sorte que mon conseil est de laisser Android vous en préoccuper. Si l'utilisateur veut quitter votre application ils peuvent appuyer sur le bouton Accueil et votre application disparaîtra de manière efficace Si le téléphone a besoin de plus de mémoire plus tard, le système d'exploitation met fin à votre application.

Tant que vous répondez correctement aux événements du cycle de vie , ni vous ni l'utilisateur ne devez vous préoccuper de savoir si votre application est toujours en cours d'exécution ou non.

Donc, si vous voulez masquer votre application, appelez moveTaskToBack() et laissez Android) décider du moment où vous devez la tuer.

88
Dave Webb

Le moyen le plus simple d'y parvenir est indiqué ci-dessous (sans affecter la gestion de la mémoire native d'Android. Il n'y a pas de processus mortel impliqué).

  1. Lancer une activité en utilisant cette intention:

    Intent intent = new Intent(this, FinActivity.class);
    intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    startActivity(intent);
    finish();
    
  2. Dans l'activité cible FinActivity.class, appelez finish () dans onCreate.

Explication des étapes:

  1. Vous créez une intention qui efface toutes les autres activités (FLAG_ACTIVITY_CLEAR_TOP) et supprimez l'activité en cours.

  2. L'activité se détruit. Une alternative est que vous pouvez créer un écran de démarrage dans FinActivity. Ceci est optionnel.

53
jordi

Android a mis en place un mécanisme permettant de fermer une application en toute sécurité, conformément à sa documentation. Dans la dernière activité quittée (généralement l'activité principale apparue au début de l'application), placez quelques lignes dans la méthode onDestroy (). L'appel à System.runFinalizersOnExit (true) garantit que tous les objets seront finalisés et les déchets collectés à la fermeture de l'application. Par exemple:

public void onDestroy() {
    super.onDestroy();

    /*
     * Notify the system to finalize and collect all objects of the
     * application on exit so that the process running the application can
     * be killed by the system without causing issues. NOTE: If this is set
     * to true then the process will not be killed until all of its threads
     * have closed.
     */
    System.runFinalizersOnExit(true);

    /*
     * Force the system to close the application down completely instead of
     * retaining it in the background. The process that runs the application
     * will be killed. The application will be completely created as a new
     * application in a new process if the user starts the application
     * again.
     */
    System.exit(0);
}

Enfin, Android ne notifiera pas une application de l'événement HOME . Vous ne pouvez donc pas fermer l'application lorsque la touche [~ # ~] de la maison [~ # ~] est enfoncée. Android réserve le DE LA MAISON événement pour que le développeur ne puisse empêcher les utilisateurs de quitter leur application.

20
Danny Remington - OMS

Vous pouvez également spécifier noHistory = "true" dans la balise pour la première activité ou terminer la première activité dès que vous démarrez la seconde (comme l'a dit David).

Autant que je sache, "force fermer" tue le processus qui héberge la machine virtuelle dans laquelle votre application s'exécute et System.exit () termine la machine virtuelle exécutant votre instance d'application. Les deux sont une forme de terminaisons abruptes et ne sont pas recommandées pour un flux d'application normal.

Il n’est pas souhaitable de capturer des exceptions pour couvrir les flux logiques qu’un programme pourrait entreprendre.

9
Samuh

J'utilise cette méthode pour fermer les activités!

public static void closeAllBelowActivities(Activity current) {
    boolean flag = true;
    Activity below = current.getParent();
    if (below == null)
        return;
    System.out.println("Below Parent: " + below.getClass());
    while (flag) {
        Activity temp = below;
        try {
            below = temp.getParent();
            temp.finish();
        } catch (Exception e) {
            flag = false;
        }
    }
}
9
amsurana

Lorsque vous lancez la deuxième activité, finish() la première immédiatement:

startActivity(new Intent(...));
finish();
8
David Hedlund

Android.os.Process.killProcess(Android.os.Process.myPid()); fonctionne bien, mais il est recommandé de laisser la Android) s'inquiéter de la gestion de la mémoire :-)

6
Arnab

Utilisez la méthode finish. C'est la méthode la plus simple et la plus facile.

this.finish();
4
Nikhil

Vous ne pouvez pas faire System.exit (), ce n'est pas sans danger.

Vous pouvez faire ceci: Process.killProcess (Process.myPid ());

4
Cytown

J'utilise ceci:

1) L'activité parente appelle l'activité secondaire avec la méthode "startActivityForResult"

2) Dans l’activité secondaire à la fermeture:

int exitCode = 1; // Select the number you want
setResult(exitCode);
finish();

3) Et dans l'activité parente, remplacez la méthode "onActivityResult":

public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    int exitCode = 1;
    if(resultCode == exitCode) {
        super.setResult(exitCode); // use this if you have more than 2 activities
        finish();
    }
}

Cela fonctionne bien pour moi.

4
molda

Gardez à l'esprit que lorsque vous utilisez des applications qui utilisent des connexions de socket persistantes, la méthode finish() ne libère pas la connexion. Dans des circonstances normales, finish() est la meilleure option, mais si vous devez absolument quitter une application et libérer toutes les ressources qu'elle utilise, utilisez killProcess. Je n'ai eu aucun problème à l'utiliser.

2
PJ420

Supposons que vous ayez une pile d'activités telle que A> B> C> D> E. Vous êtes à l'activité D et vous souhaitez fermer votre application. C'est ce que tu vas faire -

Dans Activité à partir de laquelle vous souhaitez fermer (Activité D) -

Intent intent = new Intent(D.this,A.class);
intent.putExtra("exit", "exit");
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP| Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(intent);

Dans votre RootActivity (c’est-à-dire votre activité de base, ici l’activité A) -

@Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        if (intent.hasExtra("exit")) {
            setIntent(intent);
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (getIntent() != null) {
            if (("exit").equalsIgnoreCase(getIntent().getStringExtra(("exit")))) {
                onBackPressed();
            }
        }
    }

onNewIntent est utilisé car si l'activité est active, elle obtiendra la première intention qui l'a démarrée. Pas le nouveau. Pour plus de détails - Documentation

2
Darpan

Essayez ce qui suit. Ça marche pour moi.

ActivityManager am = (ActivityManager) this.getSystemService(ACTIVITY_SERVICE);
List<ActivityManager.RunningTaskInfo> taskInfo = am.getRunningTasks(1); 
ComponentName componentInfo = taskInfo.get(0).topActivity;
am.restartPackage(componentInfo.getPackageName());
2
Sikandar

Commencez la deuxième activité avec startActivityForResult et, dans la deuxième activité, restituez une valeur qui, une fois définie dans la méthode onActivityResult de la première activité, ferme l'application principale. Je pense que c'est la bonne façon Android le fait.

2
Dayerman

Vous avez tort. Il y a un moyen de tuer une application. Dans une classe avec super classe Application, nous utilisons un champ, par exemple, killApp. Lorsque nous démarrons l'écran de démarrage (première activité) dans onResume(), nous définissons un paramètre pour false pour le champ killApp. Dans chaque activité que nous avons lorsque onResume() est appelée à la fin, nous appelons quelque chose comme ça:

if(AppClass.killApp())
    finish();

Toute activité qui va à l’écran doit appeler onResume(). Quand il est appelé, nous devons vérifier si notre champ killApp est vrai. Si c'est le cas, les activités en cours appellent finish(). Pour invoquer l'action complète, nous utilisons la construction suivante. Par exemple, dans l'action pour un bouton:

AppClass.setkillApplication(true);
   finish();
   return;
1
Peter

Voici ce que j'ai fait pour fermer l'application: Dans mon application, j'ai une classe d'activité de base, j'ai ajouté un indicateur statique appelé "applicationShutDown". Lorsque je dois fermer l'application, je la règle sur true.

Dans l'activité de base onCreate et onResume après avoir appelé les super-appels, je teste cet indicateur. Si "applicationShutDown" est vrai, j'appelle la fin de l'activité en cours.

Cela a fonctionné pour moi:

protected void onResume() {
    super.onResume();
    if(BaseActivity.shutDownApp)
    {
        finish();
        return;

    }}
1
user1942887

C'est en fait assez facile.

Pour ce faire, je sauvegarde un drapeau dans une variable statique accessible à tous. Puis, quand je sors, je mets ce drapeau et toutes mes activités vérifient ce drapeau onResume. Si le drapeau est positionné, j’émets le System.exit sur cette activité.

Ainsi, toutes les activités rechercheront le drapeau et se fermeront normalement si le drapeau est défini.

1
Mikeghtmare

J'ai résolu un problème similaire: MainActivity démarre BrowserActivity, et je dois fermer l'application lorsque l'utilisateur appuie sur Retour dans BrowserActivity - pour ne pas revenir dans MainActivity. Donc, dans MainActivity:

public class MainActivity extends AppCompatActivity {
    private static final String TAG = "sm500_Rmt.MainActivity";
    private boolean m_IsBrowserStarted = false;

et ensuite, dans OnResume:

    @Override
protected void onResume() {
    super.onResume();
    if(m_IsBrowserStarted) {
        Log.w(TAG, "onResume, but it's return from browser, just exit!");
        finish();
        return;
    }
    Log.w(TAG, "onResume");

... puis continuez OnResume. Et lorsque vous démarrez BrowserActivity:

    Intent intent = new Intent(this, BrowserActivity.class);
    intent.putExtra(getString(R.string.IPAddr), ip);
    startActivity(intent);
    m_IsBrowserStarted = true;

Et on dirait que ça marche bien! :-)

0
Sergey Skosyrev

Ce n'est pas recommandé, mais vous pouvez toujours l'utiliser. Mieux vaut utiliser cette solution au cas où vous auriez besoin de quitter l'application.

Selon moi, la meilleure solution consiste à terminer chaque activité de votre application comme ci-dessous.

Étape 1. Conservez une variable statique dans l'activité principale. Dire,

public static boolean isQuit = false;

Étape 2. Lorsque vous cliquez sur l’événement d’un bouton, définissez cette variable sur true.

mainactivity.isQuit = true;
finish();

Étape 3. Et dans chaque activité de votre application, utilisez la méthode onrestart comme ci-dessous.

@Override
protected void onRestart() {
    // TODO Auto-generated method stub
    super.onRestart();
    if(mainactivity.isQuit)
        finish();
}
0
Shankar Agarwal

Exécutez la deuxième activité en utilisant l'activité de démarrage pour le résultat:

Intent intent = new Intent(FirstActivity.this, SecondActivity.class);

//This line is important
intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);

startActivityForResult(intent, REQUEST_CODE);

Ajouter cette fonction à la première activité:

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if(rquestCode == REQUEST_CODE)
        if(resultCode == RESULT_CANCELED)
            finish();
}

Et ajoutez ceci à la deuxième activité:

@Override
public boolean onKeyDown(int keyCode, KeyEvent event)  {
    if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) {

        Log.i(TAG, "Back key pressed");
        setResult(RESULT_CANCELED);
        finish();
        return true;
    }
    return super.onKeyDown(keyCode, event);
}
0
piojo