2017-09-13 102 views
1

我在閱讀this偉大的教程,它解釋了@Component.Builder如何在Dagger 2中工作。作者做得很好,文章很簡單,但仍然存在一些令我困惑的問題,我需要澄清:匕首2的默認實現看起來是這樣的:瞭解Dagger 2 @Component.Builder註釋

組件:

@Singleton 
@Component(modules = {AppModule.class}) 
public interface AppComponent { 

    void inject(MainActivity mainActivity); 
    SharedPreferences getSharedPrefs(); 
} 

模塊:

@Module 
public class AppModule { 

    Application application; 

    public AppModule(Application application) { 
     this.application = application; 
    } 

    @Provides 
    Application providesApplication() { 
     return application; 
    } 
    @Provides 
    @Singleton 
    public SharedPreferences providePreferences() { 
     return application.getSharedPreferences(DATA_STORE, 
           Context.MODE_PRIVATE); 
    } 
} 

組件實例化:

DaggerAppComponent appComponent = DaggerAppComponent.builder() 
     .appModule(new AppModule(this)) //this : application 
     .build(); 

根據這篇文章,我們可以通過避免將參數傳遞給使用@Component.Builder@BindsInstance註釋模塊構造更加簡化這個代碼,那麼代碼會是這樣的:

成分:

@Singleton 
@Component(modules = {AppModule.class}) 
public interface AppComponent { 
    void inject(MainActivity mainActivity); 
    SharedPreferences getSharedPrefs(); 

    @Component.Builder 
    interface Builder { 
     AppComponent build(); 
     @BindsInstance Builder application(Application application);  
    } 

}

的米odule:

@Module 
public class AppModule { 

    @Provides 
    @Singleton 
    public SharedPreferences providePreferences(
            Application application) { 
     return application.getSharedPreferences(
            "store", Context.MODE_PRIVATE); 
    } 
} 

和組件實例化:

DaggerAppComponent appComponent = DaggerAppComponent.builder() 
      .application(this) 
      .build(); 

我幾乎不懂上面的代碼是如何工作的,但這裏是我不明白的一部分:我們是如何得到appModule(new AppModule(this))application(this)時我們正在實例化組件?

我希望問題很清楚,謝謝。

回答

4

TL;博士匕首將創建任何無參數的構造模型本身,如果你不通過他們和@BindsInstance使用量可能比從一個模塊提供類型來更好地優化。


首先,您有一個組件需要構建Application。因此,您構建模塊並將其傳遞給組件。

現在,使用組件構建器,您可以將綁定到單個對象的組件。這是我們上面做的一個選擇。不再需要模塊,我們可以直接向Dagger提交我們想要的組件中的對象。
@Binds一樣,爲了提供接口實現,通常可以假定Dagger可以並將優化比使用模塊的簡單方法更好的功能,因爲其意圖更加清晰。

因此,使用@BindsInstance會將該類型添加到我們的組件,以便我們不再需要該模塊來提供它。我們現在也可以從模塊構造函數中刪除參數。

當我們實例化組件時,我們是如何從appModule(new AppModule(this))得到應用程序(this)的?

由於匕首可以實例無參數模塊本身就不再需要將模塊明確地添加到組件中,我們可以用新的.application(this)調用替換該行。

+0

如果匕首可以實例無參數模塊本身,我們只是冷冷使用'DaggerAppComponent.builder()建();',還等什麼'申請(這)是爲了? –

+0

檢查你的'Component.Builder'界面!您註冊了一個將應用程序綁定到組件的方法,您必須調用它:'@BindsInstance Builder應用程序(應用程序應用程序);' –

+0

現在我明白了!非常感謝David Medenjak,你非常有幫助 –

0
@Component.Builder 
    interface Builder { 
     AppComponent build(); 
     @BindsInstance Builder application(Application application);  
    } 

當我們調用方法

應用從應用類(應用程序)

。應用(本)

它會將我們的應用程序對象設置爲AppComponent。所以在appcomponet中,應用程序實例是可用的。

所以我們可以從應用程序模塊中刪除下面的代碼,因爲匕首會自動將應用程序實例注入到需要的地方。

Application application; 
    public AppModule(Application application) { 
     this.application = application; 
    } 

    @Provides 
    Application providesApplication() { 
     return application; 
    } 

此外,Dagger使用默認構造函數實例化所有模塊。

如果你想從一個的AppModule Context對象只寫

@Module 
public class AppModule { 

    @Provides 
    Context provideContext(Application application) { 
     return application; 
    } 
}