我有这个简单的模块 SharePreferencesModule.java :
@Module(includes = ApplicationModule.class)
public class SharedPreferencesModule {
@Provides
SharedPreferences sharedPreferences(MyApp app) {
return app.getSharedPreferences("...", Context.MODE_PRIVATE);
}
@Provides
@Named("firstname")
static String getFirstname(SharedPreferences preferences) {
return preferences.getString("firstname", "");
}
}
使用此组件 SharedPreferencesComponent.java :
@Component(modules = SharedPreferencesModule.class)
public interface SharedPreferencesComponent {
void inject(MyFragment myClass);
}
这个类正在使用模块:
public MyFragment extends Fragment {
@Inject
@Name("firstname")
String firstname;
@Override
public void onAttach(Context context) {
// Not posting "Injector" code in the snippet because it is irrelevant
Injector.getSharedPreferencesComponent().inject(this);
}
}
创建MyFragment后,我成功注入了firstname,但是如果编辑了共享的prefs,我仍然引用firstname的旧值。这是正常的,因为只有当MyFragment附加时,Dagger才会提供名字。
如何与共享的首选项保持同步?
每次更新共享首选项时,是否应该重新注入MyFragment?对我来说似乎很麻烦。 或者我可以以某种方式迫使Dagger为我取这些数据?
答案 0 :(得分:3)
每次更新共享首选项时,是否应该重新注入MyFragment?
你应该只注射一次,就像你不多次调用构造函数一样。
可能会有一些例外,确实需要(或者更喜欢)再次注入,但所有这些注入都应该在开始使用你的对象之前发生。多次注入会导致不一致的状态,即不清楚哪个对象引用了注入对象的哪个版本 这可能在某些情况下有效,但会导致其他人遇到困难,无论哪种方式,您都很难设置它,确保更新所有内容。每当发生变化时,你最好只是摧毁并重新创建整个片段。
注入一个对象应该是一次完成的初始设置,之后该类应该可以使用了。
如果事情不断变化,那么Dagger并不是最适合提供它的人。你的名字可能会更好地放在一些NameSettings
类
class NameSettings {
private SharedPreferences prefs;
@Inject NameSettings(SharedPreferences prefs) {
this.prefs = prefs;
}
String getName() { return /* load from prefs */ }
void setName(String name) { /* save to prefs */ }
}
而不是直接注入名称,您现在可以注入NameSettings
并调用get / set来更新您的名字。这样您就可以随时读取和写入最新值,而无需直接处理SharedPreferences。
现在你的NameSettings
不会改变,也不需要重新注射它。
您甚至可以继续返回Observable
(例如RxJava或可观察模式的某些自定义实现),然后您可以随时监听更改并动态更新UI。
答案 1 :(得分:1)
我会@Provide
SharedPreferences
对象本身。这最小化了依赖图,使您可以读/写任何首选项。