Статьи

RxPreferences и Dagger

Я переписывал настройки (настройки) для старого приложения Android. Поскольку я использовал RxJava в приложении, я решил попробовать RxPreferences, который позволяет вам использовать SharedPreferences с реактивной оболочкой.

Я нашел это довольно хорошим, чтобы использовать, хотя сообщение в блоге, которое сопровождает это, немного устарело. Хотя я не использовал RxBinding с ним, он все же имел следующие преимущества:

Введите 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, являются их собственными.