2017-04-04 65 views
1

我遵循此guide爲我的Android應用程序製作子組件。在這裏,我定義使用名爲LoginComponent一個子組件,用於LoginActivity:匕首2:在定義子組件後注入

@Subcomponent(modules = LoginModule.class) 
public interface LoginComponent { 

    void inject(LoginActivity activity); 

    @Subcomponent.Builder 
    interface Builder { 
     Builder requestModule(LoginModule module); 
     LoginComponent build(); 
    } 
} 


@Module 
public class LoginModule { 
    @Provides 
    LoginManager provideLoginManager(LoginManagerImpl manager) { 
     return manager; 
    } 

    @Provides 
    LoginView provideLoginView(LoginViewImpl view) { 
     return view; 
    } 

    @Provides 
    LoginPresenter loginPresenter(LoginView view, LoginManager manager) { 
     return new LoginPresenterImpl(view, manager); 
    } 
} 

我定義另一個組件內此子組件:

@Module(subcomponents = LoginComponent.class) 
public interface AppModule { 
} 

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

這裏是我的LoginActivity:

public class LoginActivity extends AppCompatActivity { 

    @Inject LoginPresenter presenter; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_login); 
    } 
} 

我的問題是:

  1. 目的@Subcomponent.Builder。我不明白這一點,因爲此組件中的所有模塊都已在@Subcomponent註釋中定義。爲什麼我們應該再次複製。
  2. 我該如何在上述活動中注入LoginPresenter。

感謝

回答

3
  1. @Subcomponent.Builder遵循@Component.Builder記載相同的規則:你需要爲每一個匕首不能初始化自身模塊二傳手。 (模塊允許有構造函數參數或靜態工廠方法,這將防止Dagger創建自己的實例。)

    由於Dagger可以通過調用零參數構造函數來創建LoginModule,因此可以從Builder中刪除該方法;你不需要重新創建它。您也可以考慮製作LoginModule的方法static,這樣可以讓您將LoginModule設置爲接口或抽象類,那麼Dagger就可以避免持有對模塊的引用。最後,對於綁定兩個類的簡單的@Provides方法(例如@Provides B provideB(A a) { return a; }),您可以切換到@Binds,這將允許生成的代碼更快。

    在這一點上,你@Subcomponent.Builder成爲子特定Provider:您可以注入你的BuilderProvider<Builder>並通過調用它build()得到一個新的子實例。只要您不需要提供任何模塊實例,就不需要在構建器上使用任何其他方法。

    您可以簡單地注入一個Provider<LoginComponent>,但我在實踐中沒有看到過,並沒有親自嘗試過。

  2. 要注入一個LoginPresenter,你需要到你的AppComponent,創建一個新的LoginComponent,並通過傳入它來注入你的Activity。然而,這可能很困難,因爲你沒有給自己任何訪問注入你的LoginComponent.Builder。

    除非您想用dagger.android代替,否則您可以添加一個方法來調用您的AppComponent來創建一個新的LoginComponent。

    // This way... 
    LoginComponent createLoginComponent(); 
    
    // or this way: 
    LoginComponent.Builder createLoginComponentBuilder(); 
    

    有時你會看到一個名爲plus()第一種方式,這是一家成立於匕首1的命名約定;第一種方式也可以避免創建@Subcomponent。生成器或在AppModule中添加子組件,儘管您可能想按照自己的方式離開該結構,以便稍後可以向AppModule添加更多內容。

    要完成它,請在Activity.onCreate中,讓您的活動獲取您的應用程序,訪問其AppComponent並注入自身。

    ((YourApplication) getContext().getApplicationContext()) 
        .getApp() 
        .createLoginComponent() 
        .inject(this);