Я переписывал настройки (настройки) для старого приложения 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
|
@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 в классы, которые будут его использовать.
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 @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); } |
Использование Preference с конвертером, а также Dagger означало, что у меня не было кода преобразования типов, разбросанного по всему приложению.
Опубликовано на Java Code Geeks с разрешения Дэвида Вонга, партнера нашей программы JCG . Смотрите оригинальную статью здесь: RxPreferences и Dagger
Мнения, высказанные участниками Java Code Geeks, являются их собственными. |