2010-03-14 4 views
14

J'ai une petite application de test sur laquelle je travaille qui dispose d'une minuterie qui met à jour un textview de 100 à 0. Cela fonctionne bien, mais maintenant j'essaie de mettre l'application en pause si l'utilisateur appuie sur le bouton de retour sur le téléphone, puis redémarrez la minuterie d'où ils se sont arrêtés quand ils rouvrent l'application. Voici le code que je utilise:Problèmes d'activité onPause/onResume

@Override 
public void onPause() 
{ 
    if(this._timer_time_remaining > 0) { 
     this.timer.cancel(); 
    } 
    super.onPause(); 
    Log.v("Pausing", String.format("Pausing with %d", this._timer_time_remaining)); 
} 

@Override 
public void onResume() 
{ 
    Log.v("Resuming", String.format("Resuming with %d", this._timer_time_remaining)); 

    if(this._timer_time_remaining > 0) { 
     start_timer(this._timer_time_remaining); 
    } 
    super.onResume(); 
} 

La méthode start_timer() crée un CountDownTimer qui met à jour la textview dans la méthode onTick et met à jour la variable this._timer_time_remaining int.

CountDownTimer et _timer_time_remaining sont tous deux déclarés au niveau de la classe comme ceci:

private CountDownTimer timer; 
private int _timer_time_remaining; 

De l'impression Log.v() Je vois que la variable _timer_time_remaining a le nombre correct de secondes enregistrée OnPause est appelée, mais il est remis à 0 lorsque onResume démarre. Pourquoi la variable est-elle réinitialisée? Je pensais que l'application continuerait à fonctionner en arrière-plan avec les mêmes valeurs. Est-ce que je manque quelque chose? Tout est déclaré dans une classe qui étend l'activité.

Merci d'avance!

Note: Sous la direction de nettoyer la copie de code

Répondre

16

Si vous jetez un coup d'oeil au diagramme pour Activity lifecycle vous vous rendrez compte qu'il n'y a aucune garantie sur vous activité après OnPause est appelé. Android pourrait vous tuer Activité sans même appeler onDestroy. Vous devez enregistrer votre état en utilisant onSaveInstanceState et le restaurer en utilisant onRestoreInstanceState.

This pourrait être utile.

EDIT:

Cycle de vie couvre différents scénarios. Si vous n'avez qu'une seule activité, appuyer sur Retour équivaut à quitter votre application. Si vous avez l'activité A qui démarre l'activité B alors onSaveInstanceState est appelée pour l'activité A. Lorsque vous appuyez de nouveau sur l'activité B, elle se ferme et onRestoreInstanceState est appelée pour l'activité A. Vous essayez d'enregistrer des données entre deux exécutions distinctes de votre application. besoin d'utiliser une sorte de persistent storage pour cela.

+0

D'abord, merci pour la réponse. J'ai remplacé ma méthode onPause par la méthode onSaveInstanceState (Bundle savedInstancestate), mais elle ne semble pas être appelée lorsque j'appuie sur le bouton de retour pour quitter mon application. Aucun de mes messages LogCat n'apparaît donc je ne pense pas qu'il soit appelé du tout. Ai-je besoin d'onPause et d'onSaveInstanceState? Ou devrait onSaveInstanceState le gérer? – Blather

+0

La documentation explique ceci: "Un exemple de quand onPause() et onStop() est appelé et non cette méthode est quand un utilisateur revient de l'activité B à l'activité A: il n'est pas nécessaire d'appeler onSaveInstanceState (Bundle) sur B parce que une instance particulière ne sera jamais restaurée, de sorte que le système évite de l'appeler. " Si vous appuyez sur Retour, vous n'appelez pas onSaveInstanceState mais appuyez sur Home. –

+0

Merci de votre réponse. J'ai vu cela mentionné, mais si onSaveInstanceState n'est pas appelé quand on appuie sur le bouton précédent, il ne s'occupera pas de mon problème, n'est-ce pas? Je veux juste que le compte à rebours s'arrête lorsque le bouton de retour est pressé, puis redémarrer à partir du même endroit lorsque l'application est redémarrée à partir de l'écran d'accueil. Je peux être malentendu, mais il ne semble pas que cela accomplira cela. Merci encore pour le temps que vous avez pris pour aider jusqu'à présent, il me manque juste quelque chose ici je pense. – Blather

0

Vous pouvez simplement écrire le délai d'attente dans une base de données ou un fichier dans onPause et le lire dans onResume.

1

Je ne suis pas un expert sur Android, mais juste dire de la façon dont je pense que le minuteur comportais

this.timer.cancel(): - annulerait la minuterie, mais pas le mettre en pause

start_timer(this._timer_time_remaining): - serait « restart "la minuterie, ne continue pas de la dernière position.

Donc ce que vous voyez est correct. Chaque fois que l'heure est recommencée. Découvrez quelle est l'API pour mettre en pause la minuterie (le cas échéant).

0

Vous pouvez également essayer d'écouter les touches (onKeyDown()) pour intercepter le bouton de retour et enregistrer vos données dans une table SQLite.

2

Voilà comment je sauverais la valeur: (Quatre lignes de code)

SharedPreferences example = getSharedPreferences("example", MODE_PRIVATE); 
SharedPreferences.Editor edit = example.edit(); 
edit.putInt("time_remaining", (Integer)this._timer_time_remaining); 
edit.commit(); 

la reprise, procédez comme suit: (Deux lignes de code)

SharedPreferences example = getSharedPreferences("example", MODE_PRIVATE); 
int time_remaining = example.getInt("time_remaining", 0); 

Je me suis adapté ce de certains de mon code de travail, mais je ne l'ai pas testé dans ce format exact. Recherchez la documentation de sharedPreferences pour apprendre comment cela fonctionne.