cycle de vie onNewIntent () et écouteurs enregistrés

150

J'utilise une activité singleTop pour recevoir les intentions d'un dialogue de recherche via onNewIntent().

Ce que j'ai remarqué, c'est que ça onPause()s'appelle avant onNewIntent(), et ensuite ça appelle onResume(). Visuellement:

  • boîte de dialogue de recherche lancée
  • intention de recherche renvoyée à l'activité
  • onPause()
  • onNewIntent()
  • onResume()

Le problème est que j'ai des écouteurs enregistrés onResume()qui sont supprimés onPause(), mais ils sont nécessaires à l'intérieur de l' onNewIntent()appel. Existe-t-il un moyen standard de rendre ces auditeurs disponibles?

DJayC
la source

Réponses:

295

onNewIntent()est conçu comme un point d'entrée pour les activités singleTop qui s'exécutent déjà ailleurs dans la pile et ne peuvent donc pas appeler onCreate(). Du point de vue du cycle de vie des activités, il est donc nécessaire d'appeler onPause()avant onNewIntent(). Je vous suggère de réécrire votre activité pour ne pas utiliser ces auditeurs à l'intérieur onNewIntent(). Par exemple, la plupart du temps, mes onNewIntent()méthodes ressemblent simplement à ceci:

@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    // getIntent() should always return the most recent
    setIntent(intent);
}

Avec toute la logique de configuration en onResume()utilisant getIntent().

Rodja
la source
@Rodja voulez-vous s'il vous plaît commenter ce stackoverflow.com/questions/19092631/... aussi
Développeur
3
Relative à la question originale: garder à l' esprit si vous déplacez le code pour gérer la recherche Intentdans onResume(), votre activité va probablement essayer d'exécuter une recherche à chaque fois qu'il reprend, sans doute pas le comportement que vous voulez.
Tony Chan
1
Rodja dit: Du point de vue du cycle de vie des activités, il est donc nécessaire d'appeler onPause () avant onNewIntent () Android n'a pas BESOIN de le concevoir de cette façon. Votre activité a déjà traversé son cycle de vie pour reprendre (). Pas BESOIN pour Android d'appeler onPause (), puis d'appeler à nouveau onResume (). Si l'application est reprise, le système d'exploitation pourrait simplement appeler onNewIntent () et rester dans l'état repris.
Sani Elfishawy
Rodja dit: Du point de vue du cycle de vie des activités, il est donc nécessaire d'appeler onPause () avant onNewIntent () Android n'a pas BESOIN de le concevoir ainsi. Votre activité a déjà traversé son cycle de vie pour reprendre. Si l'acte est repris, ils pourraient simplement appeler onNewIntent () et rester dans la reprise. Le problème avec la séquence d'Android est qu'il est impossible de faire la distinction entre onPause en raison d'une action de l'utilisateur et onPause en raison d'une intention d'arrière-plan. Si vous voulez agir sur Pause uniquement dans le cas d'une action de l'utilisateur, vous êtes foutu parce que vous ne saurez pas jusqu'à l'avenir pourquoi vous passez à onPause ().
Sani Elfishawy
Le point important à noter est que getIntent () renvoie toujours l'intention d'origine. Vous pouvez utiliser setIntent (Intent) pour mettre à jour vers le nouvel Intent.
linuxjava
15

Remarque: L'appel d'une méthode de cycle de vie à partir d'une autre méthode n'est pas une bonne pratique. Dans l'exemple ci-dessous, j'ai essayé de faire en sorte que votre onNewIntent soit toujours appelé quel que soit votre type d'activité.

OnNewIntent () est toujours appelé pour les activités singleTop / Task sauf pour la première fois lorsque l'activité est créée. A ce moment, onCreate est appelé à fournir une solution pour quelques requêtes posées sur ce fil.

Vous pouvez toujours invoquer onNewIntent en le mettant dans la méthode onCreate comme

@Override
public void onCreate(Bundle savedState){
    super.onCreate(savedState);
    onNewIntent(getIntent());
}

@Override
protected void onNewIntent(Intent intent) {
  super.onNewIntent(intent);
  //code
}
Pawan Maheshwari
la source
59
En général, ce n'est pas une bonne idée d'appeler directement les méthodes du cycle de vie, non? Peut-être inoffensif, ou peut-être qu'une implémentation de base de onNewIntent () suppose que onPause () a déjà été appelée? Vraisemblablement plus sûr d'encapsuler le code de l'application dans une méthode appelable des deux endroits.
BernalKC
12
D'accord. Nous avons rencontré quelques cas extrêmes en utilisant cette approche. Mieux vaut éviter.
Saad Farooq
3
Ouais ... moi aussi je suis d'accord pour éviter cela ... c'était pour ceux qui veulent invoquer onNewIntent depuis onCreate également.
Pawan Maheshwari