Modo più efficiente per aggiornare l'UI dal servizio rispetto agli intenti?

Ho attualmente un servizio in Android che è un client VOIP di esempio in modo che ascolti per i messaggi SIP e se riceve uno si avvia una schermata attività con componenti UI.

Quindi i seguenti messaggi SIP determinano l'attività da visualizzare sullo schermo. Ad esempio se la chiamata in arrivo visualizzerà Risposta o Rifiuta o una chiamata in output, mostrerà una schermata di composizione.

  • SMS_RECEIVED non lavora su Ice Cream Sandwich?
  • Qualcuno ti preghi di spiegare RESULT_FIRST_USER
  • Come sapere quale intento è selezionato in Intent.ACTION_SEND?
  • Lettura di tag NFC
  • Come get il picker di contatti android sdk per farmi solo i risultati del telefono e non tutti i miei seguaci twitter
  • Come ricevere solo SMS da un numero specifico (Altri SMS vai in Posta in arrivo del telefono)
  • Nel minuto uso Intenti per consentire all'attività di conoscere quale stato deve essere visualizzato.

    Un esempio è il seguente:


    Intent i = new Intent(); i.setAction(SIPEngine.SIP_TRYING_INTENT); i.putExtra("com.net.INCOMING", true); sendBroadcast(i); Intent x = new Intent(); x.setAction(CallManager.SIP_INCOMING_CALL_INTENT); sendBroadcast(x); Log.d("INTENT SENT", "INTENT SENT INCOMING CALL AFTER PROCESSINVITE"); 

    Quindi l'attività avrà un destinatario di logging registrato per queste intenzioni e cambierà lo stato in base all'ultimo intento ricevuto.

    Esempio di codice come segue:


      SipCallListener = new BroadcastReceiver(){ @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if(SIPEngine.SIP_RINGING_INTENT.equals(action)){ Log.d("cda ", "Got RINGING action SIPENGINE"); ringingSetup(); } if(CallManager.SIP_INCOMING_CALL_INTENT.equals(action)){ Log.d("cda ", "Got PHONE RINGING action"); incomingCallSetup(); } } }; IntentFilter filter = new IntentFilter(CallManager.SIP_INCOMING_CALL_INTENT); filter.addAction(CallManager.SIP_RINGING_CALL_INTENT); registerReceiver(SipCallListener, filter); 

    Ciò funziona tuttavia sembra che non sia molto efficace, gli intenti avranno ampio sistema di trasmissione e intenti che devono sparare per diversi stati sembra che potrebbe diventare inefficiente più devo includere e aggiungere complessità.

    Quindi mi chiedevo se esista un altro modo più efficiente e più pulito per farlo?

    C'è un modo per mantenere intenti che trasmettono solo all'interno di un'applicazione?

    Le chiamate sarebbero una migliore idea? In caso affermativo, perché e in che modo dovrebbero essere attuati?

  • Come submit i dati a un'altra applicazione non avviata
  • Ottieni risultati da un'attività dopo la finitura (); in un test di unità Android
  • L'exception di sicurezza ha ottenuto l'invio di immagini in Facebook Messenger tramite la condivisione INTENT
  • Come potrei submit dati (text) ad altre applicazioni (come i messaggi)
  • Android WebView non carica URL
  • Come stabilire una comunicazione bidirezionale tra attività e servizio in diversi processi?
  • 2 Solutions collect form web for “Modo più efficiente per aggiornare l'UI dal servizio rispetto agli intenti?”

    UPDATE 2015:

    Questa domanda / risposta ha ancora un po 'di attività, ma è più di 5 anni e le cose sono cambiate parecchio. 5 anni fa, la risposta di seguito è stata come avrei gestito. Più tardi ho scritto una soluzione di iniezione di dipendenza molto leggera che stavo usando per un po '(che ho citato nei commenti). Oggi, risponderei a questa domanda utilizzando Dagger e RxAndroid. Pugnale per iniettare una class di "mediatore" sia nel Servizio che in tutte le attività che devono essere notificate, il Servizio spingerebbe l'aggiornamento dello stato alla class del mediatore e la class del mediatore esporrebbe un'osservabile per le attività per consumare l'aggiornamento dello stato ( al posto del ricevitore radiotrasmettitore OP).

    Risposta originale

    Di solito sottoscrivere l'applicazione e lasciare che la mia comunicazione in-app passare attraverso questa class (o avere un mediatore di properties; dell'applicazione fai il lavoro … a prescindere che l'applicazione sia il punto di ingresso del servizio per comunicare). Ho un servizio legato che ha bisogno anche di aggiornare l'interface utente (molto più semplice del tuo, ma la stessa idea) e spiega praticamente l'applicazione il suo nuovo stato e l'applicazione può quindi passare queste informazioni in un modo o nell'altro all'attuale attività triggers. È inoltre ansible mantenere un puntatore all'attività attualmente triggers (se esistono più di uno) e decidere se aggiornare o less l'attività corrente, submit l'intento di avviare un'attività diversa, ignorare il messaggio, ecc. anche sottocategoria Attività e avere la tua nuova class di attività di class dire all'applicazione che attualmente è triggers in onResume e che viene interrotta in onPause (per i casi in cui il servizio è in esecuzione in background e le attività sono tutte in pausa).

    EDIT:

    In risposta al commento, qui sono più specifiche.

    L'applicazione attualmente consiste in classi di attività e derivate dal servizio per la maggior parte. Inerentemente, ottieni funzionalità da un'istanza della class android.app.Application. Questo viene dichiarato nel tuo manifesto (per impostazione predefinita) con la seguente row:

     <application android:icon="@drawable/icon" android:label="@string/app_name"> 

    L'elemento dell'applicazione nel tuo manifesto non utilizza l'attributo android: name, quindi crea un'istanza della class predefinita android.app.Application per rappresentare il context applicativo globale.

    Nelle mie applicazioni creo una sottoclass di applicazione (ApplicationEx, ad esempio) e dico alla mia applicazione attraverso il manifesto che questa è la class da istanziare come context di applicazione globale MY. Per esempio:

     <application android:name="com.mycompany.myapp.app.ApplicationEx" android:icon="@drawable/app_icon" android:label="@string/app_name"> 

    Ora posso aggiungere methods a ApplicationEx per attività e servizi da utilizzare per comunicare. C'è sempre un'unica istanza del tuo context applicativo globale, quindi questo è il tuo punto di partenza se qualcosa deve essere globale per l'applicazione.

    Un secondo pezzo di questo è che, invece di derivare i miei servizi e le attività da Service e Activity, creo una sottoclass di ognuna con un metodo getAppContext che esegue il valore restituito di getApplicationContext (che esiste già in entrambe le classi perché derivano da Context ) alla mia class ApplicationEx.

    Così……..

    Tutto ciò che si dice, si aggiunge una properties; CurrentActivity alla class ApplicationEx di tipo Activity (o ActivityBase se lo sovrascriverai come faccio). Nel metodo OnResume di ActivityBase, si passerà ad ApplicationEx per impostare CurrentActivity su tale attività. Ora, è ansible esporre i methods su ApplicationEx per passare le informazioni direttamente all'attività corrente anziché fare affidamento sui meccanismi Intent.

    Questo è più chiaro quanto posso farlo

    È ansible submit intenti di trasmissione solo alla propria applicazione e non a livello di sistema con LocalBroadcastManager :

    Helper per registrare e submit trasmissioni di Intenti agli oggetti locali all'interno del process. Ciò ha numerosi vantaggi rispetto all'invio di trasmissioni globali con sendBroadcast (Intent):

    Sai che i dati che trasmettete non lasceranno la tua applicazione, quindi non devi preoccuparti di perdere dati privati.

    Non è ansible che altre applicazioni inviino queste trasmissioni alla tua app, per cui non wherete preoccuparvi di avere buchi di sicurezza che possono sfruttare.

    E 'più efficiente che submit una trasmissione globale attraverso il sistema.

    Tuttavia, vorrei ancora consigliare di andare con l'approccio del Servizio e localmente binding e parlando con Handler quando necessario per aggiornare i componenti UI per l'efficienza.

    L'Android è un fan Android di Google, tutto su telefoni Android, Android Wear, Android Dev e applicazioni Android Games e così via.