2015-11-04 47 views
3

我正在研究許多來源的匕首2,例如這個:http://fernandocejas.com/2015/04/11/tasting-dagger-2-on-android/ 但我仍然沒有找到我的問題的答案。匕首2 - 如何只注入到基本活動/片段

我工作在相當複雜的應用程序中,有數十個片段和幾個我想使用DI(匕首2)的活動。對於所有這些片段和活動,我有一個BaseActivity和一個BaseFragment。但是,據我閱讀和嘗試,爲了在我的MainActivity中使用@Inject,我必須在Component接口中指定它,並調用getApplicationComponent()。在onCreate方法中注入(this)。當我僅對BaseActivity執行此操作時,MainActivity中的@Inject註釋字段永遠不會被注入。更糟糕的是,在執行代碼的特定部分並拋出NPE之前,我並沒有發現這一點。

到目前爲止,這對我來說是一個難題,因爲這可能是許多崩潰的根源。我需要在Component接口中指定數十個片段和活動,並且不要忘記在每個onCreate方法中調用inject。

我會很高興聽到任何解決這一點,因爲我真的想用DI ..

代碼示例:

@Singleton 
@Component(modules = ApplicationModule.class) 
public interface ApplicationComponent { 
    void inject(BaseActivity baseActivity); 
    Analytics analytics(); 
} 

public class BaseActivity extends AppCompatActivity { 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     this.getApplicationComponent().inject(this); 
    } 
} 

public class MainActivity extends BaseActivity { 
    @Inject 
    Analytics analytics; 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     analytics.log("event1"); // THROWS NPE! 
    } 
} 
+0

大概'analytics'是空 –

回答

2

您可以無法通過注入在你的子類的屬性注入超級(因爲dagger2在編譯時工作,沒有辦法動態檢查註解屬性的子類。)

您可以將analytics移動到超級,然後它會被注入那裏。要在你的子類中注入帶註釋的字段,你必須再次調用注入。

您可以在您的基類中創建一個抽象方法,例如inject(App app)你只需處理注射。這樣你就不能「錯過」它。

如在規定的官方documentation

雖然一個類型將接受其亞型的實例的成員注入方法中,僅注入註解參數類型的成員和其超類型將被注入;亞型成員不會。

+0

好,我也必須把它付諸ApplicationComponent接口,這樣有兩兩件事必須經常做。似乎對我很痛苦:( – user1299412

+0

葉普,但至少它是可測試的;) –

+0

如果你不介意一些痛苦,一切都是可測試的:) – ZhongYu

0

動議

@Inject 分析分析;

到您的BaseActivity類中,Analytics對象在超類中被初始化並被子類自動繼承,因此您不會再獲得空值。

public class MainActivity extends BaseActivity { 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     analytics.log("event1"); 
    } }