Skip to content

Instantly share code, notes, and snippets.

@henrytao-me
Created June 19, 2015 10:52
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save henrytao-me/443e3c705ae375e22229 to your computer and use it in GitHub Desktop.
Save henrytao-me/443e3c705ae375e22229 to your computer and use it in GitHub Desktop.
RxSharedPreferences
/*
* Copyright 2015 "Henry Tao <hi@henrytao.me>"
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package me.henrytao.util;
import android.content.SharedPreferences;
import android.text.TextUtils;
import java.util.Set;
import rx.Observable;
import rx.Subscriber;
import rx.functions.Func1;
import rx.subjects.BehaviorSubject;
import static rx.android.internal.Preconditions.checkNotNull;
/**
* Created by henrytao on 6/19/15.
*/
public class RxSharedPreferences {
public static RxSharedPreferences create(SharedPreferences sharedPreferences) {
return new RxSharedPreferences(sharedPreferences);
}
public Preference<Boolean> booleanPref;
public Preference<Float> floatPref;
public Preference<Integer> intPref;
public Preference<Long> longPref;
public Preference<String> stringPref;
public Preference<Set<String>> stringSetPref;
protected SharedPreferences mSharedPreferences;
public RxSharedPreferences(SharedPreferences sharedPreferences) {
mSharedPreferences = checkNotNull(sharedPreferences, "sharedPreferences == null");
booleanPref = new Preference<>(Boolean.class, mSharedPreferences);
floatPref = new Preference<>(Float.class, mSharedPreferences);
intPref = new Preference<>(Integer.class, mSharedPreferences);
longPref = new Preference<>(Long.class, mSharedPreferences);
stringPref = new Preference<>(String.class, mSharedPreferences);
stringSetPref = new Preference<>(Set.class, mSharedPreferences);
}
public void clear() {
mSharedPreferences.edit().clear().apply();
}
public void remove(String key) {
mSharedPreferences.edit().remove(key).apply();
}
public static class Preference<T> {
private Class mClazz;
private SharedPreferences mSharedPreferences;
private BehaviorSubject<KeyValue<T>> mSubject;
public Preference(Class clazz, SharedPreferences sharedPreferences) {
mSharedPreferences = sharedPreferences;
mSubject = BehaviorSubject.create();
mClazz = clazz;
}
public T get(String key, T defValue) {
if (mClazz.isAssignableFrom(Boolean.class)) {
return (T) Boolean.class.cast(mSharedPreferences.getBoolean(key, (Boolean) defValue));
} else if (mClazz.isAssignableFrom(Float.class)) {
return (T) Integer.class.cast(mSharedPreferences.getInt(key, (Integer) defValue));
} else if (mClazz.isAssignableFrom(Integer.class)) {
return (T) Integer.class.cast(mSharedPreferences.getInt(key, (Integer) defValue));
} else if (mClazz.isAssignableFrom(Long.class)) {
return (T) Integer.class.cast(mSharedPreferences.getInt(key, (Integer) defValue));
} else if (mClazz.isAssignableFrom(String.class)) {
return (T) Integer.class.cast(mSharedPreferences.getInt(key, (Integer) defValue));
} else if (mClazz.isAssignableFrom(Set.class)) {
return (T) Integer.class.cast(mSharedPreferences.getStringSet(key, (Set<String>) defValue));
}
return null;
}
public Observable<T> observe(String key, T defValue) {
if (!mSharedPreferences.contains(key)) {
put(key, defValue);
}
return observe(key);
}
public Observable<T> observe(String key) {
return mSubject.filter(new Func1<KeyValue<T>, Boolean>() {
@Override
public Boolean call(KeyValue<T> item) {
if (item == null) {
return false;
}
return TextUtils.equals(key, item.mKey);
}
}).map(new Func1<KeyValue<T>, T>() {
@Override
public T call(KeyValue<T> item) {
return item.mValue;
}
});
}
public Observable<T> observePut(String key, T value) {
return Observable.create(new Observable.OnSubscribe<T>() {
@Override
public void call(Subscriber<? super T> subscriber) {
put(key, value);
if (!subscriber.isUnsubscribed()) {
subscriber.onNext(value);
subscriber.onCompleted();
}
}
});
}
public void put(String key, T value) {
if (mClazz.isAssignableFrom(Boolean.class)) {
mSharedPreferences.edit().putBoolean(key, (Boolean) value).apply();
mSubject.onNext(new KeyValue<T>(key, value));
} else if (mClazz.isAssignableFrom(Float.class)) {
mSharedPreferences.edit().putFloat(key, (Float) value).apply();
mSubject.onNext(new KeyValue<T>(key, value));
} else if (mClazz.isAssignableFrom(Integer.class)) {
mSharedPreferences.edit().putInt(key, (Integer) value).apply();
mSubject.onNext(new KeyValue<T>(key, value));
} else if (mClazz.isAssignableFrom(Long.class)) {
mSharedPreferences.edit().putLong(key, (Long) value).apply();
mSubject.onNext(new KeyValue<T>(key, value));
} else if (mClazz.isAssignableFrom(String.class)) {
mSharedPreferences.edit().putString(key, (String) value).apply();
mSubject.onNext(new KeyValue<T>(key, value));
} else if (mClazz.isAssignableFrom(Set.class)) {
mSharedPreferences.edit().putStringSet(key, (Set<String>) value).apply();
mSubject.onNext(new KeyValue<T>(key, value));
}
}
}
protected static class KeyValue<T> {
String mKey;
T mValue;
public KeyValue(String key, T value) {
mKey = key;
mValue = value;
}
}
}
/*
* Copyright 2015 "Henry Tao <hi@henrytao.me>"
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package me.henrytao.util;
import me.henrytao.test.RobolectricGradleTestRunner;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import android.content.Context;
import android.content.SharedPreferences;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertThat;
/**
* Created by henrytao on 6/19/15.
*/
@RunWith(RobolectricGradleTestRunner.class)
@Config(sdk = 21)
public class RxSharedPreferencesTest {
private static final String PREF_NAME = "test_app_settings";
String mKey = "key";
RxSharedPreferences mRxSharedPreferences;
String mValue;
@Before
public void before() throws Exception {
SharedPreferences sharedPreferences = RuntimeEnvironment.application.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE);
mRxSharedPreferences = RxSharedPreferences.create(sharedPreferences);
mRxSharedPreferences.clear();
}
@Test
public void testGetString_defaultValue() throws Exception {
mValue = "default";
mRxSharedPreferences.stringPref.observe(mKey, mValue).subscribe(s -> {
assertThat(s, equalTo(mValue));
});
mValue = "new value";
mRxSharedPreferences.stringPref.put(mKey, mValue);
}
@Test
public void testGetString_defaultValue2() throws Exception {
SharedPreferences sharedPreferences = RuntimeEnvironment.application.getSharedPreferences("test_app_settings", Context.MODE_PRIVATE);
RxSharedPreferences rxSharedPreferences = RxSharedPreferences.create(sharedPreferences);
mValue = "default";
rxSharedPreferences.stringPref.observe(mKey).subscribe(s -> {
assertThat(s, equalTo(mValue));
});
rxSharedPreferences.stringPref.put(mKey, mValue);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment