我一直在为旧的Android应用程序重写“设置(首选项)”活动 。 自从我在应用程序中使用RxJava以来,我决定尝试RxPreferences ,该RxPreferences允许您将SharedPreferences与反应式包装一起使用。
尽管附带的博客文章有些过时,但是我发现它的使用非常不错。 虽然我没有将RxBinding与它一起使用,但它仍然具有以下优点:
- 键入首选项 ,包括自定义类型。
- 以RxJava Observable形式观察对首选项的更改,而不必使用OnSharedPreferenceChangeListener接口。
使用Dagger注入RxPreferences
可以通过带有Dagger 2之类的库的Dependency Injection来完成首选项,以获取需要的首选项。 例如,这是Dagger模块的示例,该模块通过RxSharedPreferences设置提供应用程序范围的依赖关系:
@Module
class AppModule {
// the application context required to get the shared preferences
@Singleton
@Provides
Context provideContext(Application application) {
return application.getApplicationContext();
}
@Provides
@Singleton
SharedPreferences provideSharedPreferences(Context context) {
return PreferenceManager.getDefaultSharedPreferences(context);
}
@Provides
@Singleton
RxSharedPreferences provideRxSharedPreferences(SharedPreferences sharedPreferences) {
return RxSharedPreferences.create(sharedPreferences);
}
}
然后将RxSharedPreferences注入将使用它的类。
public class MyActivity extends AppCompatActivity {
// RxSharedPreferences injected into a field for an activity
@Inject
RxSharedPreferences rxSharedPreferences;
@Override
public void onCreate(Bundle savedInstanceState)
{
// I'm using the Dagger Android library to inject dependencies
AndroidInjection.inject(this);
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
}
private void someMethod()
{
<Preference<String> myPreference = rxSharedPreferences.getString("pref_key");
String stringFromPreference = myPreference.get();
// do something with the string obtained from the preference
}
}
直接注入首选项
另外,您可以通过在Dagger模块中设置首选项来注入首选项而不是RxSharedPreference。
class AppModule {
@Singleton
@Provides
Context provideContext(Application application) {
return application.getApplicationContext();
}
@Provides
@Singleton
SharedPreferences provideSharedPreferences(Context context) {
return PreferenceManager.getDefaultSharedPreferences(context);
}
@Provides
@Singleton
RxSharedPreferences provideRxSharedPreferences(SharedPreferences sharedPreferences) {
return RxSharedPreferences.create(sharedPreferences);
}
// Preference configured with hard-coded preference key
@Provides
@Named("myPreference")
@Singleton
Preference<String> provideMyPreference(RxSharedPreferences rxPreferences) {
return rxPreferences.getString("my_preference_key");
}
// Preference configured with preference key retrieved from string resource
@Provides
@Named("myPreferenceUsingResource")
@Singleton
Preference<String> provideMyPreferenceUsingResource(Context context, RxSharedPreferences rxPreferences) {
return rxPreferences.getString(context.getString(R.string.pref_my_preference_key));
}
}
请注意,作为一个示例,我在模块中配置了2个首选项,其中一个带有硬编码的首选项键,另一个带有从字符串资源中检索的首选项键。
我还添加了@Named注释,在这种情况下,这是为了区分两个Preferences,因为它们都是String类型。 即使我没有多个相同类型的偏好设置,我也认为对它们进行限定以获得更好的文档是一个好主意(请参阅Dagger文档以了解限定符。
然后注入首选项而不是RxSharedPreferences。
public class MyActivity extends AppCompatActivity {
@Inject
@Named("myPreference")
Preference<String> myPreference;
@Override
public void onCreate(Bundle savedInstanceState)
{
AndroidInjection.inject(this);
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
}
private void someMethod()
{
String stringFromPreference = myPreference.get();
// do something with the string obtained from the preference
}
}
然后,我们还可以使用注入的首选项来观察它的变化。
public class MyActivity extends AppCompatActivity {
@Inject
@Named("myPreference")
Preference<String> myPreference;
private Disposable disposable;
@Override
public void onCreate(Bundle savedInstanceState)
{
AndroidInjection.inject(this);
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
disposable = myPreference.asObservable()
.subscribe(pref -> doSomething(pref));
}
}
自定义首选项类型
在RxPreferences库的博客中 ,它演示了如何通过为它创建Adapter类来获得自定义类型的Preference。 在当前版本中,此类已替换为实现Preference.Converter接口的类。
这是一个简单的示例,它将存储为字符串的首选项转换为Preference <Boolean>。 首先创建Converter类:
public final class BooleanStringConverter implements Preference.Converter<Boolean> {
@NonNull
@Override
public Boolean deserialize(@NonNull String serialized) {
return Boolean.parseBoolean(serialized);
}
@NonNull
@Override
public String serialize(@NonNull Boolean value) {
return String.valueOf(value);
}
}
然后,要获取首选项,请使用带有Converter类作为参数的getObject()。 在此示例中,我将其添加到了Dagger模块中。
@Provides
@Singleton
BooleanStringConverter provideBooleanStringConverter() {
return new BooleanStringConverter();
}
@Provides
@Named("myBooleanPreference")
@Singleton
Preference<Boolean> provideMyBooleanPreference(RxSharedPreferences rxPreferences, BooleanStringConverter booleanStringConverter) {
return rxPreferences.getObject("my_preference_key", FALSE, booleanStringConverter);
}
将首选项与Converter以及Dagger一起使用,意味着我没有将类型转换代码分散在整个应用程序中。
翻译自: https://www.javacodegeeks.com/2018/03/rxpreferences-and-dagger.html