나는 한동안 dagger2와 함께 일했습니다. 그리고 각 활동 / 조각에 대해 고유 한 구성 요소 / 모듈을 만드는 것이 혼란 스러웠습니다. 이것을 명확히 도와주세요.
예를 들어, 앱이 있고 앱에는 약 50 개의 화면이 있습니다. DI 용 MVP 패턴과 Dagger2에 따라 코드를 구현합니다. 50 개의 활동과 50 명의 발표자가 있다고 가정합니다.
제 생각에는 일반적으로 다음과 같이 코드를 구성해야합니다.
앱이 열려있는 동안 사용할 모든 개체를 제공하는 AppComponent 및 AppModule을 만듭니다.
@Module public class AppModule { private final MyApplicationClass application; public AppModule(MyApplicationClass application) { this.application = application; } @Provides @Singleton Context provideApplicationContext() { return this.application; } //... and many other providers } @Singleton @Component( modules = { AppModule.class } ) public interface AppComponent { Context getAppContext(); Activity1Component plus(Activity1Module module); Activity2Component plus(Activity2Module module); //... plus 48 methods for 48 other activities. Suppose that we don't have any other Scope (like UserScope after user login, ....) }
ActivityScope 만들기 :
@Scope @Documented @Retention(value=RUNTIME) public @interface ActivityScope { }
각 활동에 대한 구성 요소 및 모듈을 만듭니다. 일반적으로 Activity 클래스 내에 정적 클래스로 배치합니다.
@Module public class Activity1Module { public LoginModule() { } @Provides @ActivityScope Activity1Presenter provideActivity1Presenter(Context context, /*...some other params*/){ return new Activity1PresenterImpl(context, /*...some other params*/); } } @ActivityScope @Subcomponent( modules = { Activity1Module.class } ) public interface Activity1Component { void inject(Activity1 activity); // inject Presenter to the Activity } // .... Same with 49 remaining modules and components.
그것들은 내가 이것을 어떻게 구현하는지 보여주는 아주 간단한 예일뿐입니다.
하지만 내 친구가 또 다른 구현을 제공했습니다.
모든 발표자를 제공 할 PresenterModule을 만듭니다.
@Module public class AppPresenterModule { @Provides Activity1Presenter provideActivity1Presentor(Context context, /*...some other params*/){ return new Activity1PresenterImpl(context, /*...some other params*/); } @Provides Activity2Presenter provideActivity2Presentor(Context context, /*...some other params*/){ return new Activity2PresenterImpl(context, /*...some other params*/); } //... same with 48 other presenters. }
AppModule 및 AppComponent를 만듭니다.
@Module public class AppModule { private final MyApplicationClass application; public AppModule(MyApplicationClass application) { this.application = application; } @Provides @Singleton Context provideApplicationContext() { return this.application; } //... and many other provides } @Singleton @Component( modules = { AppModule.class, AppPresenterModule.class } ) public interface AppComponent { Context getAppContext(); public void inject(Activity1 activity); public void inject(Activity2 activity); //... and 48 other methods for 48 other activities. Suppose that we don't have any other Scope (like UserScope after user login, ....) }
그의 설명은 다음과 같습니다. 그는 각 활동에 대해 구성 요소와 모듈을 만들 필요가 없습니다. 제 친구들의 생각이 전혀 좋지 않다고 생각 합니다만, 제가 틀렸다면 정정 해주세요. 이유는 다음과 같습니다.
많은 메모리 누수 :
- 사용자에게 2 개의 활동 만 열려 있어도 앱은 50 명의 발표자를 생성합니다.
- 사용자가 활동을 닫은 후에도 발표자는 계속 남아 있습니다.
하나의 활동에 대해 두 개의 인스턴스를 생성하려면 어떻게됩니까? (그는 어떻게 두 명의 발표자를 만들 수 있습니까?)
앱을 초기화하는 데 많은 시간이 걸립니다 (많은 발표자, 개체 등을 만들어야하기 때문).
긴 게시물에 대해 죄송합니다. 저와 제 친구를 위해 이것을 명확히하도록 도와주세요. 그를 설득 할 수 없습니다. 귀하의 의견은 매우 감사하겠습니다.
/ ------------------------------------------------- ---------------------- /
데모를 한 후 편집하십시오.
먼저 @pandawarrior 답변에 감사드립니다. 이 질문을하기 전에 데모를 만들어야했습니다. 여기 내 결론이 다른 사람에게 도움이되기를 바랍니다.
- 내 친구가 한 일은 Provides-methods에 Scope를 넣지 않는 한 메모리 누수를 일으키지 않습니다. (예 : @Singleton 또는 @UserScope, ...)
- 제공 방법에 범위가없는 경우 많은 발표자를 만들 수 있습니다. (그래서 두 번째 요점도 잘못되었습니다)
- Dagger는 필요할 때만 발표자를 만듭니다. (따라서 앱 초기화에 시간이 오래 걸리지 않을 것입니다. Lazy Injection으로 인해 혼란 스러웠습니다)
따라서 위에서 말한 모든 이유는 대부분 잘못되었습니다. 그러나 두 가지 이유로 내 친구의 생각을 따라야한다는 의미는 아닙니다.
소스의 아키텍처에 좋지 않습니다. 그가 모듈 / 구성 요소의 모든 발표자를 초기화 할 때입니다. ( 인터페이스 분리 원칙 , 단일 책임 원칙도 위반 ).
스코프 컴포넌트를 생성 할 때 생성 된 시점과 소멸 된 시점을 알 수 있으므로 메모리 누수를 방지하는 데 큰 이점이 있습니다. 따라서 각 활동에 대해 @ActivityScope를 사용하여 구성 요소를 만들어야합니다. 내 친구 구현과 함께 Provider-method => 메모리 누수에 Scope를 넣는 것을 잊었다 고 상상해 봅시다.
제 생각에는 작은 앱 (많은 종속성이 없거나 유사한 종속성이있는 몇 개의 화면)을 사용하면 친구 아이디어를 적용 할 수 있지만 물론 권장하지 않습니다.
더 읽기 선호 : Dagger 2에서 구성 요소 (개체 그래프)의 수명주기를 결정하는 요소는 무엇입니까? Dagger2 활동 범위, 얼마나 많은 모듈 / 구성 요소가 필요합니까?
그리고 한 가지 더 참고 : 객체가 언제 파괴되었는지 확인하려면 메소드의 객체를 함께 호출하면 GC가 즉시 실행됩니다.
System.runFinalization();
System.gc();
이러한 방법 중 하나만 사용하면 나중에 GC가 실행되어 잘못된 결과를 얻을 수 있습니다.
ControllerModule
이 새 항목Presenter
을 만든 다음 발표자가Activity
또는에 삽입됩니다Fragment
. 이에 찬성하거나 반대하는 확실한 의견이 있습니까?