mah*_*guy 5 android dependency-injection dagger-2
我是Dagger2在Android 上使用的新手.我创建一些类作为他们正在使用的Dagger模块context,我不能合并,组合或使用单个上下文用于他们需要的其他模块.我现在得到这个错误:
android.content.Context is bound multiple times
Run Code Online (Sandbox Code Playgroud)
SpModules:
@Module
public class SpModules {
private Context context;
public SpModules(Context context) {
this.context = context;
}
@Provides // this can be non-scoped because anyway the same instance is always returned
Context provideContext() {
return this.context;
}
@Provides
@Singleton
SP provideSharePreferences(Context context) {
return new SP(context); // use method-local Context
}
}
Run Code Online (Sandbox Code Playgroud)
RealmModule:
@Module
public class RealmModule {
private Context context;
@Provides
Context provideApplicationContext() {
return AlachiqApplication.getInstance();
}
@Provides
@Singleton
RealmConfiguration provideRealmConfiguration() {
final RealmConfiguration.Builder builder = new RealmConfiguration.Builder()
.schemaVersion(Migration.SCHEMA_VERSION)
.deleteRealmIfMigrationNeeded()
.migration(new Migration());
return builder.build();
}
@Provides
Realm provideDefaultRealm(RealmConfiguration config) {
return Realm.getInstance(config);
}
@Provides
Context provideContext() {
return this.context;
}
}
Run Code Online (Sandbox Code Playgroud)
零件:
@Component(modules = {RealmModule.class, SpModules.class})
@Singleton
public interface ApplicationComponent {
void inject(ActivityRegister target);
void inject(ActivityMain target);
void inject(ActivityBase target);
void inject(FragmentAlachiqChannels target);
void inject(SocketServiceProvider target);
}
Run Code Online (Sandbox Code Playgroud)
然后在Application类中创建Dagger2:
component = DaggerApplicationComponent.builder()
.appModules(new SpModules(this))
.build();
Run Code Online (Sandbox Code Playgroud)
我该如何解决这个问题?
这只是匕首,告诉您您正在为组件提供多次相同的类。事实上,您可以在这里以及跨不同模块对同一组件执行此操作:
@Provides
Context provideApplicationContext() {
return AlachiqApplication.getInstance();
}
@Provides
Context provideContext() {
return this.context;
}
Run Code Online (Sandbox Code Playgroud)
这些方法是不同的,但它们提供相同的依赖关系,并且没有额外的信息,dagger 无法确定Context使用哪个。
你有几个选择。如果单个上下文足以为您的所有类提供服务,那么您可以简单地删除额外的提供方法。
但是,假设您需要应用程序和其他一些上下文。您可以使用注释Named。它的工作原理如下,您使用此注释来注释您的提供方法,这基本上将为依赖项提供一个名称。就像这样:
@Module
public class SpModules {
// ...
@Provides
@Named("context")
Context provideContext() {
return this.context;
}
//...
}
@Module
public class RealmModule {
//...
@Provides
@Named("application.context")
Context provideApplicationContext() {
return AlachiqApplication.getInstance();
}
//...
}
Run Code Online (Sandbox Code Playgroud)
现在,当您使用这些依赖项时,您还需要进行注释,例如,假设您有一个依赖于应用程序上下文的对象:
public class Something {
public Something(@Named("application.context") Context context) {
//...
}
}
Run Code Online (Sandbox Code Playgroud)
或者作为一个字段:
public class Something {
@Named("application.context") Context context;
// ...
}
Run Code Online (Sandbox Code Playgroud)
或者甚至在你的模块中:
@Provides
@Singleton
SP provideSharePreferences(@Named("context") Context context) {
return new SP(context);
}
Run Code Online (Sandbox Code Playgroud)
名称可以是您想要的任何名称,只要它们一致即可。
另一种方法是使用Qualifiers. 它们的工作方式与Named注释类似,但有所不同。您将限定依赖性。假设您创建了 2 个限定符:
@java.lang.annotation.Documented
@java.lang.annotation.Retention(RUNTIME)
@javax.inject.Qualifier
public @interface InstanceContext {
}
@java.lang.annotation.Documented
@java.lang.annotation.Retention(RUNTIME)
@javax.inject.Qualifier
public @interface ApplicationContext {
}
Run Code Online (Sandbox Code Playgroud)
然后您可以使用它们来注释提供方法:
@Module
public class SpModules {
// ...
@Provides
@InstanceContext
Context provideContext() {
return this.context;
}
//...
}
@Module
public class RealmModule {
//...
@Provides
@ApplicationContext
Context provideApplicationContext() {
return AlachiqApplication.getInstance();
}
//...
}
Run Code Online (Sandbox Code Playgroud)
然后您可以按照与名称相同的方式使用它。以下是示例:
public class Something {
public Something(@ApplicationContext Context context) {
//...
}
}
public class Something {
@ApplicationContext Context context;
// ...
}
@Provides
@Singleton
SP provideSharePreferences(@InstanceContext Context context) {
return new SP(context);
}
Run Code Online (Sandbox Code Playgroud)
同样,这些名称可以是任何名称。我个人并没有花太多精力去思考它们。希望这可以帮助。
| 归档时间: |
|
| 查看次数: |
1006 次 |
| 最近记录: |