web-dev-qa-db-fra.com

Quand enregistrer / désinscrire des récepteurs de diffusion créés dans une activité?

J'ai besoin de créer un récepteur de diffusion personnalisé dans l'événement onCreate d'une activité et, évidemment, je dois annuler l'enregistrement du récepteur de diffusion dans l'événement onDestroy de l'activité

Pour plus de clarté, voici un extrait du code que j'utilise

public class AnActivity extends Activity {
    private ResponseReceiver receiver;

    public class ResponseReceiver extends BroadcastReceiver {
           public static final String ACTION_RESP =
              "mypackagename.intent.action.MESSAGE_PROCESSED";

           @Override
            public void onReceive(Context context, Intent intent) {
// TODO Start a dialogue if message indicates successfully posted to server
            }
    }   

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        IntentFilter filter = new IntentFilter(ResponseReceiver.ACTION_RESP);
        filter.addCategory(Intent.CATEGORY_DEFAULT);
        receiver = new ResponseReceiver();
        registerReceiver(receiver, filter);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        unregisterReceiver(receiver);
    }

J'ai lu que les événements onPause/onResume et onStart/onStop pour l'activité devraient également enregistrer et désenregistrer le récepteur de diffusion.

Je veux vraiment comprendre ce qui est considéré comme la meilleure pratique pour cela et pourquoi.

73
jamesc

Vous devez enregistrer et désenregistrer vos récepteurs onStart() et onStop().

La seule raison pour laquelle une activité enregistrerait BroadcastReceivers est d'utiliser les événements d'une manière ou d'une autre sur l'activité en cours, pour informer l'utilisateur d'un événement. Si onStop() a été appelée, alors Activity n'est plus au premier plan et ne peut donc pas mettre à jour l'utilisateur.

Si vous souhaitez recevoir des événements diffusés en arrière-plan, vous devriez envisager d'utiliser un service comme indiqué ici .

Comme le dit Konstantin, onDestroy() n'est pas garanti d'être appelé, et vous pouvez continuer à recevoir des émissions pendant longtemps, lorsque le Activity n'est plus ouvert.

84
SnowyTracks

Comme onDestroy() n'est pas garanti d'être appelé, vous devez utiliser onPause() pour vous désinscrire. Tenez compte du cycle de vie de votre récepteur de diffusion: avez-vous besoin qu'il soit actif, uniquement lorsque votre activité est au premier plan? Ensuite, utilisez onResume()/onPause()

19

La Android ne prescrit pas un seul endroit pour enregistrer/désinscrire les récepteurs de diffusion, mais elle mentionne les deux onStart()/onStop() et onResume()/onPause() comme possibilités.

Le facteur le plus important pour prendre cette décision est: quand votre récepteur doit-il être en mesure de faire son travail? Cela déterminera quand l'enregistrer et le désinscrire.

  • Le récepteur doit-il faire quelque chose à propos de la diffusion uniquement lorsque l'activité est focalisée? Si tel est le cas, vous pouvez l'enregistrer/le désinscrire dans onPause()/onReceive(). (Vous pouvez également utiliser une durée de vie plus longue telle que onStart()/onStop(), mais vous devez ensuite vérifier pendant la onReceive() du récepteur si l'activité est au point.)

  • Le récepteur doit-il faire quelque chose lorsqu'il est visible, même s'il n'a pas de mise au point (par exemple lorsqu'une boîte de dialogue est affichée)? Si c'est le cas, utilisez onStart()/onStop() (ou une durée de vie plus longue, mais encore une fois, le onReceive() du récepteur doit vérifier si l'activité est visible).

  • Le récepteur doit-il être informé de la diffusion même lorsque l'activité n'est pas visible? Par exemple, doit-il se rappeler que quelque chose s'est produit, de sorte que lorsque l'activité devient visible, elle peut refléter la situation qui en résulte? Ensuite, vous devez utiliser onCreate()/onDestroy() pour vous inscrire/désinscrire. (Notez qu'il existe d'autres façons d'implémenter ce type de fonctionnalité.)

Si vous vous inscrivez dans onStart(), ne les enregistrez pas non plus dans onResume(), car cela serait redondant: onResume() n'est jamais appelé sans onStart() être appelé en premier.

Gardez également à l'esprit qu'il est préférable de garder onPause () aussi léger que possible :

l'exécution de onPause () est très brève et ne donne pas nécessairement suffisamment de temps pour effectuer des opérations de sauvegarde. Pour cette raison, vous ne devez pas utiliser onPause () pour enregistrer des données d'application ou d'utilisateur, effectuer des appels réseau ou exécuter des transactions de base de données; ce travail peut ne pas se terminer avant la fin de la méthode. Au lieu de cela, vous devez effectuer des opérations d'arrêt à charge élevée pendant onStop ().

Il est vrai que onDestroy() est non garanti d'être appelé si le système tue votre processus afin d'économiser de la mémoire. Cependant, si le processus est interrompu, le processus ne recevra pas de diffusion de toute façon. Dans ce cas, est-il vraiment nécessaire de désenregistrer les récepteurs de diffusion?

8
LarsH

Android peut tuer votre application en omettant la méthode onStop(). La meilleure façon de résoudre cette situation consiste à enregistrer BroadcastReceiver dans la méthode onResume() et à annuler l'enregistrement dans onPause().

5
ukson

Vous devez enregistrer et désinscrire votre diffusion dans les méthodes onResume () et onPause ().

si vous vous inscrivez dans onStart () et désenregistrez-le dans onStop (). cette fois, vous obtiendrez le problème suivant.

si l'écran de votre appareil est verrouillé, cette heure onStop () est appelée et si vous déverrouillez cette heure onStart () n'est jamais appelée. c'est pourquoi vous l'avez enregistré et désenregistré dans les méthodes onResume () et onPause ().

0