我正在学习Dagger 2并正在开发一款应用。我有一个设置模块,它取决于依赖于共享首选项管理器的设置管理器。我的问题是我的设置模块在调用之前没有注入设置管理器。该设置管理器需要一个SharedPrefsManager,它也没有被注入任何地方。
我做错了什么?
依赖性顺序的片段:
@Module
public class SettingsModule {
@Inject SettingsManager manager;
@Provides
@TimeControl
int[] provideResetTime(){
return manager.getResetTime();
}
@Provides
@ThemeControl
int provideThemeID(){
return manager.getTheme();
}
}
取决于设置管理器:
public class SettingsManager{
private SharedPreferencesManager manager;
@Inject
SettingsManager(SharedPreferencesManager manager){
this.manager = manager;
}
}
取决于共享首选项管理器:
public class SharedPreferencesManager {
private static SharedPreferencesManager instance = null;
public static SharedPreferencesManager getInstance(){return instance;}
String prefsKey = "SHAREDPREFSKEY";
SharedPreferences sharedPrefs = null;
Context applicationContext = null;
@Inject
SharedPreferencesManager(@ApplicationContext Context applicationContext){
this.prefsKey = prefsKey;
this.applicationContext = applicationContext;
sharedPrefs = applicationContext.getSharedPreferences(prefsKey,Context.MODE_PRIVATE);
instance = this;
}
}
答案 0 :(得分:1)
@Module
public class SettingsModule {
@Inject SettingsManager manager;
@Provides
@TimeControl
int[] provideResetTime(){
return manager.getResetTime();
}
@Provides
@ThemeControl
int provideThemeID(){
return manager.getTheme();
}
}
应该是
@Module
public class SettingsModule {
@Provides
@TimeControl
int[] resetTime(SettingsManager manager) {
return manager.getResetTime();
}
@Provides
@ThemeControl
int themeId(SettingsManager manager) {
return manager.getTheme();
}
}
请注意您的提供商没有范围,因此(AFAIK)获得themeId()
的通话和获得resetTime()
的通话很可能每次都会创建一个新的SettingsManager
。
因此可能希望将@Singleton
放在您提供的课程上。
@Singleton
public class SharedPreferencesManager {
private SharedPreferences sharedPrefs = null;
String prefsKey = "SHAREDPREFSKEY";
Context applicationContext = null;
@Inject
SharedPreferencesManager(Context applicationContext) {
this.applicationContext = applicationContext;
sharedPrefs = applicationContext.getSharedPreferences(prefsKey, Context.MODE_PRIVATE); // why isn' this in a module?
}
}
@Singleton
public class SettingsManager{
private SharedPreferencesManager manager;
@Inject
SettingsManager(SharedPreferencesManager manager){
this.manager = manager;
}
}
答案 1 :(得分:0)
我认为您不应该在模块中添加@Inject
注释,因为它们构建为创建依赖项并且仅通过对象图或简单构造函数接收其他依赖项。
以下是一个示例,说明如何避免模块中的@Inject注释以及之后的构造函数注入器。
<强> SettingsModule.java 强>
@Module
public class SettingsModule {
@Provides
@TimeControl
int[] provideResetTime(SettingsManager manager) {
return manager.getResetTime();
}
@Provides
@ThemeControl
int provideThemeID(SettingsManager manager) {
return manager.getTheme();
}
@Provides
SettingsManager provideSettingsManager(SharedPreferencesManager sharedPreferencesManager) {
return new SettingsManager(sharedPreferencesManager);
}
@Provides
SharedPreferencesManager provideSharedPreferencesManager(@ApplicationContext Context context) {
return new SharedPreferencesManager(context);
}
}
<强> SettingsManager.java 强>
public class SettingsManager {
private SharedPreferencesManager manager;
SettingsManager(SharedPreferencesManager manager) {
this.manager = manager;
}
}
<强> SharedPreferencesManager.java 强>
public class SharedPreferencesManager {
private static SharedPreferencesManager instance = null;
private SharedPreferences sharedPrefs = null;
String prefsKey = "SHAREDPREFSKEY";
Context applicationContext = null;
SharedPreferencesManager(Context applicationContext) {
this.applicationContext = applicationContext;
sharedPrefs = applicationContext.getSharedPreferences(prefsKey, Context.MODE_PRIVATE);
instance = this;
}
public static SharedPreferencesManager getInstance() {
return instance;
}
}
通过这种方式,您可以将所有注入逻辑留给您的模块,具体类别不必担心自己注入类。