2017-03-16 28 views
2

我有一個應用程序,讓我們說15個屏幕。 主要有3個,完全獨立的活動:如何使用單活動應用程序時組織Dagger2模塊和組件

  • LoginActivity - 相當明顯的,有些登錄事情
  • MainActivity - 最大的一個,最importat
  • TheOtherOneNotRelevantAtTheMoment

我決定用Conductor,因爲我發現Fragment的生命週期太複雜了,對我而言Conductor現在是「熱狗屎」

我有很多Conductor的控制器。他們大多數是XXXListController與相應的XXXDetailController。所有這些控制器僅在中生效MainActivity。這就像「單一活動應用程序」。 LoginActivity基本上是由於來自第三方OAuths的回調,如FbLogin & Google登錄。我只是試圖使MainActivity完全是我的 - 沒有任何其他奇怪的行爲。

爲了組織依賴關係,我決定使用Dagger2。我在Spring和JavaEE方面有着相當不錯的經驗,所以我認爲這很容易。

我認識幾個模塊,沒有任何問題:

AppModule - 我喜歡服務器地址等應用程序相關的東西 AndroidModule - 事情就像SharedPreferencesApplication

然後,我已經差不多「即興」以及如何組織我的觀點。這是我的本錢:

  • 3其他範圍:ActivityScopeControllerScopeServiceScope - 不相關的。
  • 各自Controller有它自己的對應Module & Component。我讀過這不是一個好主意,但我確定 - 每個Controller都是非常獨立的,並且它有自己獨特的依賴關係。
  • ApplicationComponent當然是層次結構的根源。
  • MainActivityComponent是的ApplicationComponent
  • XXXControllerComponent一個@Subcomponent是的MainActivityComponent

一個@Subcomponent要注入內MainActivity依賴我使用,我發現這個代碼很常見:

protected void injectDependencies(ApplicationComponent component) { 
    component.plus(new MainActivityModule(this)).inject(this); 
} 

的當我想爲我的Controller創建&注入依賴關係時出現問題。

MainActivity如下所示:

@ActivityScope 
@Subcomponent(modules = { 
     MainActivityModule.class 
}) 
public interface MainActivityComponent { 

    XXXListComponent newXXXListComponent(XXXListModule xxxListModule); 

    void inject(MainActivity activity); 
} 

目前,典型Controller看起來是這樣的:

@ControllerScope 
@Subcomponent(modules = { 
     XXXListModule.class 
}) 
public interface XXXListComponent { 
    void inject(XXXListController controller); 
} 

和相應的Module

@Module 
public class XXXListModule { 

    private XXXListController listController; 

    public XXXListModule(XXXListController listController) { 
     this.listController = listController; 
    } 

    @Provides 
    @ControllerScope 
    public XXXListController getMainView() { 
     return ListController; 
    } 
// other not important 
} 

基本上每個Controller應該是單身 - 我不知道想在MainActivity內部有兩個實例 - 但這不是'必備'。

問題是如何創建Controller正確的方法。目前,MainActivity做如下:

router.pushController(RouterTransaction.with(new XXXListController())); 

我不知道這一點,爲什麼手動創建Controller

裏面onCreateView()Controller我注入所有所需的依賴 - 在我看來非常醜陋的方式:

((MainActivity) getActivity()).getMainActivityComponent() 
    .newXXXListComponent(new XXXListModule(this)) 
    .inject(this); 

這個長的問題可以幫助我組織有關匕首我的知識 - 也許有人覺得它有用。但!對於那些達到這一線的Stackoverflowers來說,這是一個好方法,還是有其他更好的方法來做到這一點?

+0

有人想要採取聲音? –

回答

0

我不確定我是否完全理解您的問題,但由於您有多個活動,您可能需要在應用程序內部進行注入而不是MainActivity。 否則,他們將不再是單身人士,因爲在他們之間移動時活動會重新創建。例如,如果你犯了一個名爲ConductorApplication類:

public class ConductorApplication extends Application { 
    static AppComponent app_component; 
    static ClockComponent component; 

    @Override 
    public void onCreate() { 
     super.onCreate(); 
     app_component = DaggerAppComponent.builder().appModule(new AppModule(this)).build(); 
     component = createComponent(); 
    } 



    protected ClockComponent createComponent() { 
     return DaggerClockComponent.builder().build(); 
    } 

    public static ClockComponent getClockComponent() { 
     return component; 
    } 

    public ClockComponent component() { 
     return component; 
    } 

    public static AppComponent GetAppComponent() { 
     return app_component; 
    } 
} 

內。然後當你的控制器內HomeController

public class HomeController extends BaseController { 

    private HomeViewModel homeViewModel; 
    private ControllerHomeBinding binding; 


    @Inject 
    Clock clock; 

    @NonNull 
    @Override 
    protected View inflateView(@NonNull LayoutInflater inflater, @NonNull ViewGroup container) { 
     ConductorApplication.getClockComponent().inject(this); 
     return inflater.inflate(R.layout.controller_home, container, false); 
... 
} 

創建如您inflateView()內如果還沒有,你可能需要添加:

<application 
    android:name=".ConductorApplication" 
    ... 
    <activity 
     android:name=".MainActivity" 
     ... 
    </activity> 
</application> 

裏面你AndroidMainifest.xml