2016-08-02 106 views
2

我有一個ApplicationComponent它提供了訪問我的庫: LocationRepository,PlaylistRepository,...匕首2多進程依賴

這些倉庫都是@Singleton。 目前爲止這麼好。

我的問題是,我需要從另一個進程中的服務訪問這些存儲庫之一(LocationRepository)。

我可以在該服務中執行new LocationRepository(params)(並且由於服務生命週期與應用程序的生命週期無關,所以我確實需要另一個實例),但這不是很安全。
如果我改變服務在匕首中的創建方式,我可能會忘記更新服務。

那麼有沒有辦法讓一個組件的一部分(這裏是LocationService)分別聲明並在兩個不同的組件中以相同的方式實例化?

回答

0

ComponentA.java

@Component(modules = ModuleA.class) 
public interface ComponentA { 

} 

ComponentB.java

@Component(modules = ModuleB.class) 
public interface ComponentB { 

} 

ModuleA.java

@Module 
public class ModuleA { 
    @Provides 
    @Named("LocationA") 
    LocationService locationService() { 
     return new LocationService(<your_params>); 
    } 
} 

ModuleB.java

@Module 
public class ModuleB { 
    @Provides 
    @Named("LocationB") 
    LocationService locationService() { 
     return new LocationService(<your_params>); 
    } 
} 

而在你的活動/服務

@Inject @Named("LocationA") LocationService locationService; 

@Inject @Named("LocationB") LocationService locationService; 
+0

這確實允許我使用不同的@Named聲明組件兩次,但它不能保證注入到LocationRepositories構造函數中的對象是相同的 – Teovald

+0

您可以創建一個模塊來提供您需要的用於LocationRepos的參數,有2個組件使用該模塊。他們必須有相同的範圍。 – mbmc

1

如果我理解正確的,你要確保你的LocationRepository的定義(和實例化邏輯)橫跨兩個過程是相同的。

如果出現這種情況,您可以將其拖入自己的庫模塊,並讓這兩個進程都將該模塊作爲依賴關係。你甚至可以在那裏放置一個@Component界面。

我不會推薦它。

你最終會得到同一個單例的兩個實例。這是不可避免的,因爲進程彼此隔離,不共享內存。每個都有自己的虛擬機。這會導致難以調試的數據競爭,因爲這兩個進程讀取和寫入單個資源。

對我來說,更有意義的是一個進程將「擁有」它,另一個進程將通過進程間通信訪問它,例如,通過AIDL界面,如Google Play服務客戶端。

我想一個進程承載一個長壽命的服務,另一個進程承載您的用戶界面。在這種情況下,您的服務是單身人士的天然擁有者,您的UI過程將使用與服務通信的存儲庫實現。這甚至可以參與注射;創建一個模塊@Provide是一個LocationRepository,並給它一個綁定的服務連接。

這都是真正的高層次;我希望這是有道理的,是有幫助的。如果可以,歡迎提供更多細節!

+0

我主要想知道如何在兩種不同的注射中表達這個共享的定義:-)。你是對的,這兩個實例將獨立於可能的數據競賽。在我的具體使用情況下,這不是一個真正的問題(我有一個讀取/寫入的UI和一個只讀訪問的IntentService)。儘管如此,將回購協議完全轉移到單獨的流程是有意義的。 – Teovald