98 votes

Android équivalent à NSNotificationCenter

Dans le processus de portage d'une application iPhone sur Android, je recherche le meilleur moyen de communiquer au sein de l'application. Les intentions semblent être la voie à suivre, est-ce la meilleure (seule) option? NSUserDefaults semble beaucoup plus léger que les intentions en termes de performances et de codage.

Je devrais également ajouter que j'ai une sous-classe d'application pour state, mais que je dois informer une autre activité d'un événement.

357voto

Shiki Points 6342

Le meilleur équivalent que j'ai trouvé est LocalBroadcastManager qui fait partie de l' Android Support Package.

À partir de la LocalBroadcastManager de la documentation:

De l'aide pour vous inscrire et envoyer des diffusions des Intentions aux objets locaux au sein de votre processus. C'est a un certain nombre d'avantages par rapport à l'envoi de diffusion mondiale avec sendBroadcast(Intention):

  • Vous savez que les données sont de radiodiffusion ne laissera pas votre application, afin de ne pas besoin de s'inquiéter à propos de la fuite de données privées.
  • Il n'est pas possible pour d'autres applications pour envoyer ces émissions à votre application, donc vous n'avez pas besoin de s'inquiéter d'avoir des trous de sécurité qu'ils peuvent exploiter.
  • Il est plus efficace que l'envoi d'une diffusion mondiale, à travers le système.

Lors de l'utilisation de cela, vous pouvez dire que l' Intent est équivalent à une NSNotification. Voici un exemple:

ReceiverActivity.java

Une activité que les montres pour les notifications pour l'événement nommé "custom-event-name".

@Override
public void onCreate(Bundle savedInstanceState) {

  ...

  // Register to receive messages.
  // This is just like [[NSNotificationCenter defaultCenter] addObserver:...]
  // We are registering an observer (mMessageReceiver) to receive Intents
  // with actions named "custom-event-name".
  LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver,
      new IntentFilter("custom-event-name"));
}

// Our handler for received Intents. This will be called whenever an Intent
// with an action named "custom-event-name" is broadcasted.
private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
  @Override
  public void onReceive(Context context, Intent intent) {
    // Get extra data included in the Intent
    String message = intent.getStringExtra("message");
    Log.d("receiver", "Got message: " + message);
  }
};

@Override
protected void onDestroy() {
  // Unregister since the activity is about to be closed.
  // This is somewhat like [[NSNotificationCenter defaultCenter] removeObserver:name:object:] 
  LocalBroadcastManager.getInstance(this).unregisterReceiver(mMessageReceiver);
  super.onDestroy();
}

SenderActivity.java

La deuxième activité qui envoie/émissions de notifications.

@Override
public void onCreate(Bundle savedInstanceState) {

  ...

  // Every time a button is clicked, we want to broadcast a notification.
  findViewById(R.id.button_send).setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
      sendMessage();
    }
  });
}

// Send an Intent with an action named "custom-event-name". The Intent sent should 
// be received by the ReceiverActivity.
private void sendMessage() {
  Log.d("sender", "Broadcasting message");
  Intent intent = new Intent("custom-event-name");
  // You can also include some extra data.
  intent.putExtra("message", "This is my message!");
  LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}

Avec le code ci-dessus, chaque fois que le bouton R.id.button_send est cliqué, l'Intention est diffusé et est reçu par mMessageReceiver en ReceiverActivity.

La sortie de débogage devrait ressembler à ceci:

01-16 10:35:42.413: D/sender(356): Broadcasting message
01-16 10:35:42.421: D/receiver(356): Got message: This is my message! 

7voto

RuiAAPeres Points 14372

4voto

Shlomi Hasin Points 6

J'ai trouvé que l'utilisation de l'EventBus de Goyave lib est le moyen le plus simple pour publier-souscrire-le style de la communication entre les composants sans nécessiter de composants à inscrire explicitement l'un avec l'autre

voir leur échantillon sur https://code.google.com/p/guava-libraries/wiki/EventBusExplained

// Class is typically registered by the container.
class EventBusChangeRecorder {
  @Subscribe public void recordCustomerChange(ChangeEvent e) {
    recordChange(e.getChange());
  }

// somewhere during initialization
eventBus.register(this);

}

// much later
public void changeCustomer() {
  eventBus.post(new ChangeEvent("bla bla") );
} 

vous pouvez ajouter la lib simplement sur Android Studio par l'ajout d'une dépendance à votre construction.gradle:

compile 'com.google.guava:guava:17.0'

4voto

AngraX Points 622

Vous pouvez utiliser ceci: http://developer.android.com/reference/android/content/BroadcastReceiver.html, ce qui donne un comportement similaire.

Vous pouvez vous inscrire récepteurs par programme à l'aide du Contexte.registerReceiver(BroadcastReceiver, IntentFilter) et saisir les intentions envoyé par le Contexte.sendBroadcast(Intention).

Notez, cependant, que d'un récepteur, de ne pas obtenir des notifications si son activité (cadre) a été mis en pause.

0voto

Vous pouvez utiliser les références faibles.

De cette façon, vous pouvez gérer la mémoire vous-même et ajouter et supprimer des observateurs comme vous s'il vous plaît.

Lorsque vous addObserver ajouter ces paramètres - cast que le contexte de l'activité, vous l'ajoutez à l'interface vide, ajouter un nom de notification, et l'appel à la méthode à exécuter l'interface.

La méthode à exécuter l'interface aurait une fonction qui est appelée à exécuter pour renvoyer les données que vous êtes de passage à quelque chose comme ceci

public static interface Themethodtorun {
        void run(String notification_name, Object additional_data);
    }

Créer une observation de la classe qui invoque une référence avec une interface vide. Également construire votre Themethodtorun interface à partir du contexte passés dans le addobserver.

Ajouter l'observation d'une structure de données.

Pour appeler ce serait la même méthode a cependant tout ce que vous devez faire est de trouver la notification nom dans la structure de données, utilisez la Themethodtorun.exécuter(notification_name, données).

Cela permettra d'envoyer un rappel de l'endroit où vous avez créé un observateur avec un nom de notification. N'oubliez pas de les retirer lors de votre fait!

C'est une bonne référence pour les références faibles.

http://learningviacode.blogspot.co.nz/2014/02/weak-references-in-java.html

Je suis dans le processus de transfert de ce code de github. Gardez les yeux ouverts!

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