2015-01-09 78 views
3

場景:我有一個Controller(普通Java類),它必須能夠引導幾個Slave s。爲什麼AIDL/Messenger綁定到服務?

Slave的性質可以不同,使得它可以是:

  1. Service,讓我們稱之爲一個ServiceSlave:此對象的生命週期通常是從應用程序的組件(比如說,它的不同之不依賴於當前活動)
  2. 一個簡單的Java類,比方說ObjectSlave:此對象的生命週期是有些結合到其所創建的範圍(也就是說,當前活動)

這兩種Slave有什麼共同點,那就是它們可以駐留在不同的進程


因爲這最後的「規定」,我馬上把我的注意AIDL/MessengerControllerSlave之間通信的形式,因爲它提供了IPC。

然而,似乎AIDL(進而Messenger,因爲它應該是基於AIDL以及)只被,如果你是一個Service工作定義。也就是說,我無法實現基於AIDL的界面,而無需IBinder對象,該對象通常在onServiceConnected方法中提供。

第一個問題:可以AIDL真的只能用於處理Service嗎?如果是這樣,爲什麼這樣呢?

現在,考慮我的情況。正如任何其他優秀的開發人員一樣,我希望編寫一個優雅的界面,允許Controller對每個Slave進行試點,無論其性質如何。到目前爲止,我唯一想到的解決方案包括使用IntentBroadcastReceiver s,全部方便地包裝在專用的Java類中。

第二個問題:這是唯一可行的方法嗎?我在監督什麼?


編輯

我想我應該已經給上什麼Controller元素實際上沒有更多的細節。它是一個與幾個UI小部件鬆散耦合的組件,他們訂閱了它。它已被設計(自願),因此它不需要參考Context。所以它不需要需要直接使用 UI小部件,但這些小部件依次取決於Controller

+0

OK,你編輯的信息,我很困惑什麼的真正目標控制器/從屬範例是。如果它完全在你的應用中的「Activity」內部(不需要Context),那麼你根本不需要'Service',AIDL或者'Messenger'。這些都是跨越進程邊界時使用的,或者('Service')有一些不是以UI爲中心的運行。如果您只是將其用作內部發布 - 訂閱類型系統,那麼您必須定義類和接口。這就是說,你可能想看看EventBus或Otto作爲可能的第三方助手。 –

+0

好吧,所以我在解釋這個問題時顯然有問題:)我的主要問題是關於如何在'Controller'和'Slave'之間進行通信,其中後者可能是也可能不是'Service'。通訊必須是進程間的(因爲'Controller'和'Slave'可能運行在不同的進程上),但它也可能在同一進程內。 – Sebastiano

+0

但是,擁有'活動'時只有'Controller'存在嗎? –

回答

3

這是一個很好但不是簡單的問題。像大多數情況一樣,解決這類問題有多種方法。首先要檢查的是您的Controller是否需要或使用UI組件。如果沒有,那麼你需要將它封裝在Service中。Activity生命週期是這樣的,它只會在屏幕上顯示的時候纔會運行。一旦用戶按下HOME或BACK,它將分別停止或銷燬。通過通知或從您的應用程序啓動另一個應用程序將產生類似於按HOME的效果:您的Activity將被暫停。

因此,假設你並不需要/想爲您Controller UI,您在您的處置有許多事情:

  1. 通過將一個自定義的AIDL接口讓您服務「綁定」服務。不難,但不是因爲心靈的佯攻。
  2. 讓您的服務迴應自定義Intent s採取一些行動。 Service然後可以回退廣播或啓動特定的「奴隸」Activity。如果對此感興趣,請探索使用IntentService來更好地管理線程並防止應用程序的ANR。
  3. 與前一個類似,請使用自定義Intent,並讓您的奴隸發送一個Messenger對象作爲Intent中的附加內容。此時,Service可以發送消息到Messenger,該消息由從屬服務器Activity擁有,並將被傳送到特定的Handler

你並不需要選擇2和3暴露接口的自定義AIDL你是在正確的,如果你打算使用一個綁定的服務必須定義一個AIDL接口和你的Service.onBind()方法必須返回一個實例你的binder接口存根實現。

所有這一切都說,你可以使用3種方法中的任何一種來實現你的目標,使用駐留在ActivityService實例中的從屬類。使用AIDL或Messenger方法的優點是減少了上下文切換(效率更高),因爲您沒有發送對象。每次發送Intent時,發件人都會聯繫在系統過程中運行的ActivityManagerService以解決將要傳送的地址。使用AIDL和Messenger,只有最初的bindService()startService()呼叫可以撥打ActivityManagerService。在那之後,通信在兩個進程之間使用直接綁定來執行。

+0

好聚集!您能否指出使用這些概念的開源原生應用程序? – Nova

2

變成AIDLBinder不與Service s連在一起。

雖然這是事實,結合到ServiceIBinder參考僅提供,該框架提供了Binder類,它已經實現了IBinder接口。

而且,一個Binder實例可以跨進程透明地工作,並且不需要在Service環境中生存。


[仍然制定,將提供關於如何構造可直接使用粘合劑的實例實施方案]