2017-09-13 80 views
16

我有舊的Android/java代碼,它包含兩個派生從IntentService, 和這些服務而不是運行在單獨的進程。LiveData vs Handler and LocalBroadcast

問題是關於從這些IntentService返回結果的方式。通過使用Handler + Runnable,在主循環運行的代碼

一個服務返回結果:

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

另一種是使用LocalBroadcastManager.getInstance(this).sendBroadcast(in);要發送消息給Activity,和Activity經由BroadcastReceiveronResume訂閱上的消息,並在退訂。

我說得對嗎,在這兩種情況下都可以使用LiveData來簡化事情嗎?

IntentService應該創建LiveData,誰想要的結果應該observe它, 和新數據到達時IntentService應該叫postValue, 或可能存在一些暗礁,防止LiveData這裏使用?

+0

你檢查了這一點: https://stackoverflow.com/questions/44204978/how-to-update-livedata-of-a-viewmodel-from-background-service-and-update-ui –

+0

是的你可以這樣做 –

+0

使用ResultReceiver進行Activity到IntentService的通信,可以在這些組件之間交換數據。它對替代解決方案很有用。 –

回答

3

我認爲LiveData不會幫助您將Service的任何數據發送到其他組件。

從任何Service到其他組件的溝通問題是您通常不會獲得對Service的直接引用,因此您無法直接「訂閱」通知。

理論上,如果Service運行在相同的過程中,您可以綁定它,獲取對Service對象的引用,然後直接執行預訂。但是,這往往是一個矯枉過正的問題,我不認爲這種模式被廣泛使用。

在你的例子,有兩種通信機制:

  1. 服務靜態達到應用對象並設置一些數據。這是通過全球國家的溝通,通常被認爲是反模式。通過LocalBroadcastManager

  • 通信從上述兩種機制,我會用僅#2和避免#1不惜一切代價。

    返回LiveData

    爲了能夠從Service獲得LiveData對象,您需要參考Service。這通常是不可能的,除非你在相同的過程中綁定Service,或者使用一些涉及全局狀態的醜陋黑客。

    因此,LiveData在這方面的用處非常有限。

    順便說一下,雖然LocalBroadcastManager沒問題,但我發現這個機制太複雜和限制。因此,如果Service在相同的過程中運行,我傾向於使用EventBus以便從Service與其他組件進行通信(反之亦然)。

    您可以在SQLite benchmarking application中看到我前幾天寫的這種溝通的例子。在此應用程序中,TestService將狀態更改和測試結果作爲粘滯事件發佈到EventBusTestActivity訂閱這些事件。

  • 1

    這兩種方法都適用於使用LiveData,因爲LiveData的目的是讓它在另一個線程上,並且在某些事情發生變化時仍然通知用戶。好像它肯定會取代LocalBroadcastManager.getInstance(this).sendBroadcast(in);,你的IntentService會postValue。只要有你的活動或任何需要了解變化的東西成爲觀察者。

    +0

    「只有你的活動或任何需要注意到變化的東西才能成爲觀察者」 - 這應該如何完成? – Vasiliy

    相關問題