Domanda

Nel processo di porting di un'applicazione iPhone oltre a Android, sto cercando il modo migliore per comunicare all'interno della app. Intenti sembrano essere la strada da percorrere, è questo il migliore (solo) l'opzione? NSUserDefaults sembra peso molto più leggero di Intenti fare in termini di prestazioni e di codifica.

Vorrei anche aggiungere Ho una sottoclasse richiesta di stato, ma ho bisogno di fare un'altra attività a conoscenza di un evento.

È stato utile?

Altri suggerimenti

Il migliore che ho trovato è equivalente LocalBroadcastManager che fa parte del < a href = "http://developer.android.com/sdk/compatibility-library.html"> Android Support Package .

Dalla documentazione LocalBroadcastManager:

  

Helper per iscriversi e inviare le trasmissioni di intenti per oggetti locali all'interno del vostro processo. Questo è ha una serie di vantaggi rispetto l'invio di trasmissioni globali con sendBroadcast (Intent):

     
      
  • Si sa che i dati che si sta Broadcasting non lascerà la vostra applicazione, quindi non è necessario preoccuparsi di perdite di dati privati.
  •   
  • Non è possibile per altre applicazioni di inviare queste trasmissioni per la vostra applicazione, quindi non è necessario preoccuparsi di avere buchi di sicurezza che possono sfruttare.
  •   
  • E 'più efficiente di invio di una trasmissione globale attraverso il sistema.
  •   

Quando si utilizza questo, si può dire che un Intent è un equivalente ad un NSNotification. Ecco un esempio:

ReceiverActivity.java

Un'attività che gli orologi per le notifiche per l'evento denominato "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 seconda attività che trasmette / trasmette le notifiche.

@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);
}

Con il codice di cui sopra, ogni volta che il pulsante R.id.button_send viene cliccato, un intento è in onda e viene ricevuto da mMessageReceiver in ReceiverActivity.

L'output di debug dovrebbe essere simile a questo:

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! 

Ecco qualcosa di simile a @Shiki risposta, ma dal punto di vista degli sviluppatori iOS e il centro di notifica.

Per prima cosa creare una sorta di servizio di NotificationCenter:

public class NotificationCenter {

 public static void addObserver(Context context, NotificationType notification, BroadcastReceiver responseHandler) {
    LocalBroadcastManager.getInstance(context).registerReceiver(responseHandler, new IntentFilter(notification.name()));
 }

 public static void removeObserver(Context context, BroadcastReceiver responseHandler) {
    LocalBroadcastManager.getInstance(context).unregisterReceiver(responseHandler);
 }

 public static void postNotification(Context context, NotificationType notification, HashMap<String, String> params) {
    Intent intent = new Intent(notification.name());
    // insert parameters if needed
    for(Map.Entry<String, String> entry : params.entrySet()) {
        String key = entry.getKey();
        String value = entry.getValue();
        intent.putExtra(key, value);
    }
    LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
 }
}

Poi, si avrà anche bisogno di qualche tipo enum per essere sicuro di errori nella codifica con le stringhe - (NotificationType):

public enum NotificationType {

   LoginResponse;
   // Others

}

Ecco (gli osservatori aggiungere / rimuovere) l'utilizzo ad esempio nelle attività di:

public class LoginActivity extends AppCompatActivity{

    private BroadcastReceiver loginResponseReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
           // do what you need to do with parameters that you sent with notification

           //here is example how to get parameter "isSuccess" that is sent with notification
           Boolean result = Boolean.valueOf(intent.getStringExtra("isSuccess"));
        }
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);

        //subscribe to notifications listener in onCreate of activity
        NotificationCenter.addObserver(this, NotificationType.LoginResponse, loginResponseReceiver);
    }

    @Override
    protected void onDestroy() {
        // Don't forget to unsubscribe from notifications listener
        NotificationCenter.removeObserver(this, loginResponseReceiver);
        super.onDestroy();
    }
}

ed ecco finalmente il modo in cui la notifica postale per NotificationCenter da qualche richiamo o servizio riposo o qualsiasi altra cosa:

public void loginService(final Context context, String username, String password) {
    //do some async work, or rest call etc.
    //...

    //on response, when we want to trigger and send notification that our job is finished
    HashMap<String,String> params = new HashMap<String, String>();          
    params.put("isSuccess", String.valueOf(false));
    NotificationCenter.postNotification(context, NotificationType.LoginResponse, params);
}

Questo è tutto, evviva!

Si potrebbe utilizzare questo: http://developer.android.com/reference /android/content/BroadcastReceiver.html , che dà un comportamento simile.

È possibile registrare i ricevitori di programmazione tramite Context.registerReceiver (BroadcastReceiver, IntentFilter) e sarà catturare intenti inviate attraverso Context.sendBroadcast (Intent).

Si noti, però, che un ricevitore non sarà possibile ottenere le notifiche se la sua attività (contesto) è stato messo in pausa.

Ho trovato che l'uso di EventBus di Guava lib è il modo più semplice per la pubblicazione-iscrizione-stile di comunicazione tra i componenti senza richiedere componenti a esplicitamente registrare uno con l'altro

vedere il loro campione sul https://code.google.com/p/ guava-librerie / 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") );
} 

è possibile aggiungere questa lib semplicemente su Android Studio con l'aggiunta di una dipendenza al vostro build.gradle:

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

Si potrebbe utilizzare riferimenti deboli.

In questo modo si potrebbe gestire la memoria se stessi e aggiungere e rimuovere gli osservatori come ti pare.

Quando si addObserver aggiungere questi parametri -. Cast che contesto dall'attività che si sta aggiungendo in all'interfaccia vuoto, aggiungere un nome di notifica, e chiamare il metodo all'interfaccia run

Il metodo per eseguire l'interfaccia avrebbe una funzione che viene chiamata run per restituire i dati che si sta passando qualcosa di simile

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

Creare una classe di osservazione che richiama un riferimento con un'interfaccia vuota. Anche costruire l'interfaccia Themethodtorun dal contesto viene passato nel addobserver.

Aggiungi l'osservazione ad una struttura di dati.

Per chiamare sarebbe lo stesso metodo ma tutto quello che dovete fare è trovare il nome di notifica specifico nella struttura di dati, utilizzare il Themethodtorun.run (notification_name, dati).

Questo invierà una richiamata a dove mai si è creato un osservatore con un nome notifica specifica. Non dimenticare di toglierli quando il fatto!

Questo è un bene di riferimento per i riferimenti deboli.

http://learningviacode.blogspot.co. NZ / 2014/02 / deboli riferimenti-in-java.html

Sono in fase di caricamento di questo codice a GitHub. Tenete gli occhi aperti!

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top