アプリケーション、DBサービスなど、いくつかの標準シングルトンを提供するシングルトンスコープモジュールがあります。ただし、アクティビティの場合、アクティビティのプレゼンターを作成する別のモジュールがあり、アプリケーションコンテキストを渡す必要があります。ただし、プロジェクトをコンパイルしようとすると、次のエラーが発生します。
Error:(13, 1) error: xxx.SplashComponent scoped with @xxx.ViewScope may not reference bindings with different scopes:
@Provides @Singleton xxx.ApplicationModule.provideAppContext()
これが私のアプリケーションモジュールのスニペットです:
@Singleton
@Module
public class ApplicationModule {
private Application app;
public ApplicationModule(Application app) {
this.app = app;
}
@Provides
@Singleton
@Named("ui")
Scheduler provideUIScheduler() {
return AndroidSchedulers.mainThread();
}
@Provides
@Singleton
@Named("io")
Scheduler provideIOScheduler() {
return Schedulers.io();
}
@Provides
@Singleton
Application provideApplication() {
return app;
}
@Provides
@Singleton
Context provideAppContext() {
return app;
}
}
そして、これがアクティビティモジュールとコンポーネントです。
@Module
public class SplashModule {
private final FragmentManager fragmentManager;
public SplashModule(FragmentManager fragmentManager) {
this.fragmentManager = fragmentManager;
}
@Provides
@ViewScope
Presenter getPresenter(Context context) {
return new SplashPresenter(context, fragmentManager);
}
}
成分:
@ViewScope
@Component(modules = {SplashModule.class, ApplicationModule.class})
public interface SplashComponent {
void inject(SplashActivity activity);
}
私は何が間違っているのですか?
私は何が間違っているのですか?
この:
@ViewScope
@Component(modules = {SplashModule.class /*View scoped*/,
ApplicationModule.class/*Singleton scoped*/})
コンポーネントには、スコープなしまたはスコープがsameスコープのモジュールのみを含めることができます。複数のコンポーネントを使用する必要があります。
アプリケーションからの依存関係を含めるには、それらを別のコンポーネントに含める必要があります。 ApplicationComponent
。これを行う場合、2つのオプションがあります。SplashComponent
をSubComponent
のApplicationComponent
として宣言するか、コンポーネントへの依存関係としてApplicationComponent
を追加します。依存関係として追加する場合は、依存関係にアクセスできるように、必ずApplicationComponent
にもメソッドを指定してください。
例えばコンポーネントの依存関係を使用する場合:
@Component(modules = {ApplicationModule.class})
public interface ApplicationComponent {
void inject(MyApplication app);
// todo: also add getters for your other dependencies you need further down the graph
Application getApplication();
}
@Component(modules = {SplashModule.class}, dependencies={ApplicationComponent.class})
public interface SplashComponent {
// as before
}
私の理解から、ダガー2のいくつかの重要なポイントを説明したいと思います。
主演者:
「コンポーネント」は、モジュールと注入が行われる場所の間のブリッジです。
「モジュール」は、注入されるオブジェクトを宣言する場所です。
「スコープ」は、関連する注射ストーリーの寿命のようなものです。
どのように機能しますか?
void inject(BaseFragment baseFragment);
*******コンポーネントのモジュールで提供されたオブジェクトをサブコンポーネントに公開します****
DbHelper dbHelper();
例:
@Singleton
@Component(modules = { ApplicationModule.class, NetworkModule.class })
public interface ApplicationComponent {
void inject(BaseActivity baseActivity);
DbHelper dbHelper();
}
@PerService @Component(dependencies = ApplicationComponent.class, modules = ServiceModule.class)
public interface ServiceComponent {
void inject(SyncService service);
}
// SyncService.Java
@Inject DbHelper dbHelper; (even Singleton scoped)
private void setupInjector() {
ServiceComponent mServiceComponent = DaggerServiceComponent.builder()
.applicationComponent(getApplicationComponent())
.serviceModule(new ServiceModule(this))
.build();
mServiceComponent.inject(this);
}
スコープなしオブジェクトと(シングルトンおよびPerService)スコープ付きオブジェクトの両方をSyncService.classに挿入できます。
スコープルール:
- タイプがスコープ注釈でマークされている場合、同じスコープで注釈が付けられているコンポーネントでのみ使用できます。
- コンポーネントがスコープアノテーションでマークされている場合、そのアノテーションのあるタイプまたはアノテーションのないタイプのみを提供できます。
- サブコンポーネントは、その親コンポーネントの1つで使用されるスコープ注釈を使用できません。
このコンテキストでは、コンポーネントにはサブコンポーネントも含まれます。
注意:-スコープ注釈を使用するモジュールは、同じスコープで注釈が付けられたコンポーネントでのみ使用できます。ここをチェック 。