Я переписывал настройки (настройки) для старого приложения Android. Поскольку я использовал RxJava в приложении, я решил попробовать RxPreferences, который позволяет вам использовать SharedPreferences с реактивной оболочкой.
Я нашел это довольно хорошим, чтобы использовать, хотя сообщение в блоге, которое сопровождает это, немного устарело. Хотя я не использовал RxBinding с ним, он все же имел следующие преимущества:
- Предпочтения набираются, включая пользовательские типы.
- Наблюдение за изменениями предпочтения в качестве наблюдаемой RxJava вместо необходимости использовать интерфейс OnSharedPreferenceChangeListener .
Введите RxPreferences с помощью Dagger
Получить настройки там, где они нужны, можно с помощью Dependency Injection с такими библиотеками, как Dagger 2 . Например, это пример модуля Dagger, который предоставляет зависимости области приложения с настройкой RxSharedPreferences :
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
|
@Moduleclass 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 в классы, которые будут его использовать.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
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 }} |
Введите предпочтения напрямую
В качестве альтернативы вы можете ввести предпочтения, а не RxSharedPreferences, установив предпочтения в модуле Dagger.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
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, которая в данном случае должна различать два предпочтения, поскольку они оба имеют тип String. Даже если у меня не было нескольких предпочтений одного и того же типа, я думаю, что это хорошая идея, чтобы квалифицировать их для лучшей документации (см. Документацию Dagger, чтобы узнать о квалификаторах).
Затем введите предпочтения вместо RxSharedPreferences.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
|
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 }} |
Затем мы также можем использовать введенное предпочтение, чтобы наблюдать за изменениями в нем.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
|
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.Converter .
Вот простой пример, который преобразует предпочтение, хранящееся в виде строки, в предпочтение <Boolean>. Сначала создайте класс Converter:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
|
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); }} |
Затем, чтобы получить предпочтение, используйте getObject () с классом Converter в качестве параметра. В этом примере я добавил его в модуль Dagger.
|
01
02
03
04
05
06
07
08
09
10
11
12
|
@Provides@SingletonBooleanStringConverter provideBooleanStringConverter() { return new BooleanStringConverter();}@Provides@Named("myBooleanPreference")@SingletonPreference<Boolean> provideMyBooleanPreference(RxSharedPreferences rxPreferences, BooleanStringConverter booleanStringConverter) { return rxPreferences.getObject("my_preference_key", FALSE, booleanStringConverter);} |
Использование Preference с конвертером, а также Dagger означало, что у меня не было кода преобразования типов, разбросанного по всему приложению.
| Опубликовано на Java Code Geeks с разрешения Дэвида Вонга, партнера нашей программы JCG . Смотрите оригинальную статью здесь: RxPreferences и Dagger
Мнения, высказанные участниками Java Code Geeks, являются их собственными. |