77 votes

Forcer l'application à redémarrer lors de la première activité

Pour une raison inconnue, je ne peux pas mon application laissant correctement pour que quand je pousse le bouton home et l’icône de l’application à nouveau, je reprends où je me trouvais dans l’App je voudrais forcer l’application à redémarrer à la première activité.

Je suppose que cela a quelque chose à voir avec onDestroy() ou peut-être onPause(), mais je ne sais pas quoi faire.

157voto

Marc Points 786

Voici un exemple pour redémarrer votre application de manière générique à l'aide de PackageManager:

 Intent i = getBaseContext().getPackageManager()
             .getLaunchIntentForPackage( getBaseContext().getPackageName() );
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
 

31voto

AAverin Points 322

La solution marqué comme "réponse" fonctionne, mais a un inconvénient qui était essentiel pour moi. Avec FLAG_ACTIVITY_CLEAR_TOP votre activité cible obtiendrez onCreate appelé avant votre activité ancienne de la pile reçoit onDestroy. Alors que j'ai été compensation de certains objets nécessaires dans onDestroy j'ai dû workaroud.

C'est la solution qui a fonctionné pour moi:

public static void restart(Context context, int delay) {
    if (delay == 0) {
        delay = 1;
    }
    Log.e("", "restarting app");
    Intent restartIntent = context.getPackageManager()
            .getLaunchIntentForPackage(context.getPackageName() );
    PendingIntent intent = PendingIntent.getActivity(
            context, 0,
            restartIntent, Intent.FLAG_ACTIVITY_CLEAR_TOP);
    AlarmManager manager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
    manager.set(AlarmManager.RTC, System.currentTimeMillis() + delay, intent);
    System.exit(2);
}

L'idée est de tirer un PendingIntent via AlarmManager qui sera appelé un peu plus tard, de donner une activité vieille pile un certain temps à disparaître.

15voto

jqpubliq Points 7677

si vous voulez toujours commencer à la racine, définissez android: clearTaskOnLaunch sur true pour votre activité racine

9voto

Rishi Points 618
  android:clearTaskOnLaunch="true"
  android:launchMode="singleTask"
 

Utiliser cette propriété dans le fichier manifeste en classe de départ (première activité)

2voto

Mike Venzke Points 434

La réponse de Marc fonctionne très bien, sauf que dans mon cas, d'où mon activité principale a un launchMode de singleTop. Une fois que je lance cette intention, puis accédez à de nouvelles Activités et appuyez sur le bouton home de l'appareil, puis de lancer mon application à nouveau à partir de l'icône de l'application, j'arrive à la fin de la création d'une nouvelle instance de l'Activité principale, avec mon activité précédente sur la pile de retour.

Conformément à cette question c'est parce que les intentions ne correspondent pas. En regardant adb dumpsys activity, je vois que depuis mon android standard lanceur, le paquet est nulle, alors que quand je le fais, comme Marc l'indique, le but paquet est le nom de mon colis. Cette différence entraîne leur correspondent pas et pour démarrer une nouvelle instance lorsque l'icône de l'application est frappa de nouveau et la principale activité n'est pas sur le dessus.

Cependant, sur d'autres lanceurs, comme sur le Kindle, le paquet est mis sur le lanceur intention, j'ai donc besoin d'une méthode générique permettant de gérer des lanceurs. J'ai ajouté des méthodes statiques comme tel:

static boolean mIsLaunchIntentPackageNull = true;    

public static boolean isLaunchIntent(Intent i) {
    if (Intent.ACTION_MAIN.equals(i.getAction()) && i.getCategories() != null
            && i.getCategories().contains(Intent.CATEGORY_LAUNCHER)) {
        return true;
    }

    return false;
}

public static void handleLaunchIntent(Intent i) {
    if (isLaunchIntent(i)) {
        if (i.getPackage() != null) {
            mIsLaunchIntentPackageNull = false;
        }
        else {
            mIsLaunchIntentPackageNull = true;
        }
    }
}

avec un rentrer à la maison mécanisme comme ceci:

    Intent intentHome = appContext.getPackageManager()
            .getLaunchIntentForPackage( appContext.getPackageName());
    intentHome.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

    // need to match launcher intent exactly to avoid duplicate activities in stack
    if (mIsLaunchIntentPackageNull) {
        intentHome.setPackage(null);
    }
    appContext.startActivity(intentHome);

puis l'activité principale définie dans mon manifeste, j'ai ajouté cette ligne:

public void onCreate(Bundle savedInstanceState) {
    [class from above].handleLaunchIntent(getIntent());

cela fonctionne pour moi sur le kindle et mon téléphone, et me permet de réinitialiser correctement l'application w/o ajout d'une autre instance de l'activité principale.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X