2017-09-13 23 views
16

Ich habe alten Android/Java-Code, der zwei abgeleitet von IntentService, und diese Dienste nicht in separaten Prozessen ausgeführt wird.LiveData vs Handler und LocalBroadcast

Die Frage ist über die Art und Weise, Ergebnis von diesen IntentService zurückzugeben.

Ein Service Rückergebnis von Handler + Runnable verwenden, Code in Hauptschleife ausgeführt wird:

new Handler(Looper.getMainLooper()).post(new Runnable() { 
    @Override 
    public void run() { 
     MyApplication.get().setFoo(someThing); 
    } 
}); 

das andere ist verwendet LocalBroadcastManager.getInstance(this).sendBroadcast(in); Nachricht an Activity zu schicken, und Activity abonnieren via BroadcastReceiver auf Nachricht in onResume, und abmelden in .

Bin ich richtig, und in beiden Fällen ist es möglich, LiveData zu verwenden, um die Dinge zu vereinfachen?

IntentService sollte LiveData erstellen und wer will Ergebnis sollte es observe, und wenn neue Daten IntentService sollte postValue ankommt nennen, oder kann es einige Riffe Nutzung von LiveData hier zu verhindern?

+0

haben Sie diese ausgecheckt: https://stackoverflow.com/questions/44204978/how-to-update-livedata-of-a-viewmodel-from-background-service-and-update-ui –

+0

Sie ja kann dies tun –

+0

Verwenden Sie ResultReceiver für Aktivität zu IntentService-Kommunikation, können Sie die Daten zwischen diesen Komponenten austauschen. Es ist nützlich für eine alternative Lösung. –

Antwort

3

Ich denke, dass LiveData Ihnen beim Senden von Daten von Service zu anderen Komponenten nicht helfen wird.

Das Problem mit der Kommunikation von Service zu anderen Komponenten ist, dass Sie in der Regel keine direkte Referenz auf die Service erhalten, daher können Sie Benachrichtigungen nicht direkt "abonnieren".

Theoretisch, wenn die Service im gleichen Prozess ausgeführt wird, können Sie es binden, erhalten Sie einen Verweis auf Service Objekt und dann führen Sie direkt Abonnement. Dies ist jedoch oft ein Overkill und ich sehe nicht, dass dieses Muster weit verbreitet ist.

In Ihrem Beispiel gibt es zwei Kommunikationsmechanismen:

  1. Dienst statisch Anwendungsobjekt erreicht und einige Datensätze. Dies ist eine Kommunikation durch den globalen Staat und wird allgemein als ein Anti-Pattern betrachtet.
  2. Kommunikation über LocalBroadcastManager

Aus den beiden oben genannten Mechanismen, würde ich nur 2 # verwenden und # 1 unter allen Umständen vermeiden.

Zurück zu LiveData.

Um LiveData Objekt aus der Service zu bekommen, müssen Sie einen Verweis auf diese Service haben. Dies ist normalerweise nicht möglich, es sei denn, Sie binden Service in demselben Prozess oder verwenden einen hässlichen Hack, der den globalen Status beinhaltet.

Daher ist die Nützlichkeit von LiveData in diesem Zusammenhang sehr begrenzt.

Übrigens, während LocalBroadcastManager in Ordnung ist, finde ich diesen Mechanismus zu kompliziert und einschränkend. Wenn Service in demselben Prozess ausgeführt wird, verwende ich daher lieber EventBus, um von Service zu anderen Komponenten zu kommunizieren (oder umgekehrt).

Ein Beispiel für eine solche Kommunikation können Sie in SQLite benchmarking application, die ich vor einigen Tagen schrieb. In dieser App sendet TestService Statusänderungen und Testergebnisse an EventBus als klebrige Ereignisse, und TestActivity abonniert diese Ereignisse.

1

Beide Methoden funktionieren mit der Verwendung von LiveData, da der Zweck von LiveData darin besteht, sie in einem anderen Thread zu haben und trotzdem Benutzer zu benachrichtigen, wenn sich etwas geändert hat. Es scheint, als würde es LocalBroadcastManager.getInstance(this).sendBroadcast(in); definitiv ersetzen und Ihr IntentService würde nachValue. Lassen Sie Ihre Aktivität oder etwas, das sich der Änderungen bewusst sein muss, zum Beobachter werden.

+0

"Lassen Sie Ihre Aktivität oder etwas, das sich der Veränderungen bewusst sein muss, zum Beobachter werden" - wie genau sollte das gemacht werden? – Vasiliy

Verwandte Themen