2016-08-12 63 views
3

我有一個名爲MainActivity的Activity啓動一個名爲MainService的服務。它也綁定了服務,所以MainActivity可以訪問MainService中的方法和公共變量。是否有可能以相反的方式做到這一點,即服務能夠訪問活動的方法?服務可以訪問活動中的變量嗎?

我希望以這種方式實現它,因爲我在onResume()中設置了MainActivity中的一個變量,並且在第一次啓動時服務在onResume()運行時尚未啓動,因此在那個時間點該服務仍然爲空。

+0

我從意向服務中的應用程序類訪問變量。不確定活動。 –

+0

爲什麼不使用共享屬性呢? –

+1

我不認爲它可以。我也叫這個糟糕的設計。服務應該獨立於UI的東西。如果服務需要來自UI的值,請設計UI以在服務中設置值。 –

回答

1

這個回答假設問題的服務在不同的進程中運行:

是的,這是可能的。總體思路是,不僅您的Activity通過某個AIDL定義的接口綁定遠程Service,而且它還實現了Service所知的其他AIDL接口,並將其自身設置爲遠程Service的回調目標。

您必須有2個AIDL文件:第一個描述Service的接口,第二個描述Activity的接口。

這種方案的實施是非常相似的「遠程服務回調」,在this answer來形容,雖然「回調」的方法將不再是void,但回報你感興趣的值。

設計注意事項:

上述方案將允許您從Activity獲得值,但我認爲您不應該採取這種方式。從你的用例的描述看來,當Activity恢復時,你只想將某個值傳遞給Service。由於您的Service已被綁定,您可以簡單地將方法setSomeValue(int value)添加到其AIDL定義中,並從onServiceConnected()回調中調用此方法。

+1

僅當您想在不同應用程序之間共享服務時,才需要AIDL文件。 – piotrpo

+0

@piotrpo,好點!我只是假定涉及IPC,但現在我發現在服務所處的過程中沒有提到它。 – Vasiliy

0

是的,這是可能的。 你必須在你的服務做準備的方法即可返回您的活動服務綁定剛過:

public void bindActivity(MyActivity activity){...} 

然後服務綁定到活動後,只需要調用此方法MyActivity.this作爲參數。

但是...

你可能不應該這樣做。更爲明確的解決方案是使用LocalBroadcastManager傳遞事件和數據,或者使用一些更有效的解決方案(如Otto)來做同樣的事情,但仍然是 - 無需從另一個組件的字段/方法直接訪問。

+0

「服務」依賴於「活動」並不是一個好主意。如果這個方法的參數是某個接口,並且'MainActivity'只是簡單地實現它,那將會更加乾淨。 – Vasiliy

+0

在我看來,唯一真正「乾淨」的解決方案就是一些基於消息的解決方案。當然,根據OOD規則引入一些接口是個好主意,但仍然是 - 這個問題不是關於設計,而是實現。 – piotrpo

+0

不需要消息傳遞 - 「服務」被綁定,因此只需一個簡單的函數調用即可。接口是實現的一部分,否則實現不乾淨;) – Vasiliy

相關問題