Tout d'abord, je sais que l'on ne devrait pas vraiment tuer/redémarrer une Application sur Android. Dans mon cas d'utilisation que je veux en usine réinitialiser mon application dans un cas particulier où un serveur envoie une information spécifique pour le client. L'utilisateur peut uniquement être connecté sur le serveur avec UNE seule instance de l'application (i.e. plusieurs dispositifs ne sont pas autorisés). Si une autre instance obtient que "connecté"-verrouiller toutes les autres instanecs de l'utilisateur pour supprimer leurs données (factory-reset), en raison de la cohérence. Il est possible de forcer pour obtenir le verrou, car l'utilisateur peut supprimer l'application et de la réinstaller ce qui pourrait donner lieu à une instance-id et l'utilisateur n'a pas pu libérer le verrou plus. Par conséquent, il est possible de forcer pour obtenir le verrou.
En raison de cette force-possibilité nous devons toujours vérifier dans un des cas concrets qu'il a de la serrure. Qui est fait sur (presque) chaque requête au serveur. Le serveur peut envoyer un "mal-lock-id". Si c'est détecté, l'application cliente doit tout effacer.
C'était le cas d'utilisation. Pas pour la mise en œuvre-question:
J'ai un Activity
Un qui commence le Login Activity
L ou les applications principales Activity
B selon un sharedPrefs champ. Après le démarrage de L ou B, il se ferme de lui-même, de sorte que seul L ou B est en cours d'exécution.
Ainsi, dans le cas où l'utilisateur est déjà connecté, B est actuellement en cours.
B commence à C. C des appels startService
de la IntentService
D. Que les résultats de cette pile:
(A) > B > C > D
à partir de la onHandleIntent méthode de D un événement est envoyé à un ResultReceiver R.
R, qui gère aujourd'hui le cas échéant, de fournir à l'utilisateur une boîte de dialogue dans laquelle il peut choisir d'usine réinitialiser l'application (supprimer db, sharedPrefs etc.)
Après la factory-reset, je veux redémarrer l'application (pour fermer toutes les activités) et seulement de commencer Un nouveau qui se lance ensuite le Login Activity
L et des finitions de lui-même:
(A) > L
Les boîtes de dialogue onClick méthode ressemble à ceci:
@Override
public void onClick(DialogInterface dialog, int which) {
// will call onCancelListener
MyApplication.factoryReset(); // (deletes db, clears sharedPrefs etc.)
Intent i = new Intent(MyApp.getContext(), A.class);
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
MyApp.getContext().startActivity(i);
}
Et c'est l' MyApp
classe:
public class MyApp extends Application {
private static Context context;
@Override
public void onCreate() {
super.onCreate();
context = getApplicationContext();
}
public static Context getContext() {
return context;
}
public static void factoryReset() {
// ...
}
}
Le Problème maintenant est que si j'utilise l' FLAG_ACTIVITY_NEW_TASK
les Activités B et C sont toujours en cours d'exécution. Si j'ai frappé à l'arrière btn sur la page d' Activity
je vois C, mais je veux revenir à l'écran d'Accueil.
Si je n'aime pas mettre la FLAG_ACTIVITY_NEW_TASK
j'obtiens l'erreur:
07-07 12:27:12.272: ERROR/AndroidRuntime(9512): android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?
Je ne peux pas utiliser les Activités' Context
, parce que l' ServiceIntent
D pourrait également être appelée à partir d'une tâche de fond qui est démarré par l' AlarmManager
.
Alors, comment pourrais-je résoudre ce à l'activité de la pile devient: (A) > L ?