Android.jpg
需求分析
本文介紹一個SharedPreference的使用的工具類,在Android開發的過程中不可避免的會使用SharedPreference來緩存一個數據,(1)如果頻繁使用的話還是最好把存取操作放在子線程去處理;(2)如果不寫一個關于SharedPerference的工具類,沒法復用很多操作,(3)如果每個對應的業務的數據都寫對應的存取刪除操作的話,到項目后期會有很多,難以維護;
針對上面的三個問題實現一個比較通用可擴展性強的工具里,SharedPerference支持六種數據:String,Boolean,Int,Long,Float和Set<String>,大部分業務都可以支持,當需要保存Object和List<Object>,均可以通過使用Object->Json->String再進行保存,SharedPerference是保存在xml文件中鍵值對,所以有兩個重要的屬性就是fileName和keyName,所以
SharePerferenceUtil的包含兩個內部類:FILE_KEYS和VALUE_KEYS作為索引。
public class SPUtil {
public static final class FILE_KEYS{
public static final String APP_STATUS = "app_status";
public static final String USER_INFO = "user_info";
}
public static final class VALUE_KEYS{
public static final String IS_LOGIN = "is_login";
public static final String USER = "user";
public static final String MOBILE_LOGIN_LIST = "mobile_login_list";
}
...
讀取成功后的回調接口:
public interface SPResultListener<T> {
void onResult(T t);
}
當存取List數據時需要Id作為唯一標識,所以Object必須實現接口:
public interface ShareCacheableData {
String getId();
}
1、首先基本數據類型,以Boolean為例:
存數據,調用RxJava使得寫操作在I/O線程中進行:
public static final synchronized void saveBoolean(final String fileKey, final String valueKey, final boolean value){
Observable.create(new Observable.OnSubscribe<Object>() {
@Override
public void call(Subscriber<? super Object> subscriber) {
SharedPreferences sp = OpenEyeApplication.getInstance().getSharedPreferences(fileKey,Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
editor.putBoolean(valueKey,value);
editor.commit();
}
}).subscribeOn(Schedulers.io()).subscribe();
}
讀數據,調用RxJava使得讀取操作在I/O線程中進行,讀取成功后在UI線程中進行的回調:
public static final void getBoolean(final String fileKey, final String valueKey, final SPResultListener<Boolean> resultListener) {
Observable.fromCallable(new Callable<Boolean>() {
@Override
public Boolean call() throws Exception {
SharedPreferences sp = OpenEyeApplication.getInstance().getSharedPreferences(fileKey, Context.MODE_PRIVATE);
return sp.getBoolean(valueKey, false);
}
}).subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<Boolean>() {
@Override
public void call(Boolean value) {
value = (value == null) ? false:value;
if (resultListener != null) {
resultListener.onResult(value);
}
}
});
}
2、存取實體對象,和存取基本的數據多了一個轉String的過程,
保存實體對象:
public static final <T extends Serializable> void saveModel(final String fileKey, final String valueKey, final T t){
Observable.create(new Observable.OnSubscribe<Object>() {
@Override
public void call(Subscriber<? super Object> subscriber) {
SharedPreferences sp = OpenEyeApplication.getInstance().getSharedPreferences(fileKey,Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
editor.putString(valueKey,new Gson().toJson(t));
editor.commit();
}
}).subscribeOn(Schedulers.io()).subscribe();
}
讀取實體對象:
public static final <T extends Serializable> void getModel(final String fileKey, final String valueKey, final Class<T> clazz, final SPResultListener<T> resultListener) {
Observable.fromCallable(new Callable<T>() {
@Override
public T call() throws Exception {
SharedPreferences sp = OpenEyeApplication.getInstance().getSharedPreferences(fileKey, Context.MODE_PRIVATE);
String sResult = sp.getString(valueKey, "");
if (TextUtils.isEmpty(sResult)) {
return null;
} else {
T t = new Gson().fromJson(sResult, clazz);
return t;
}
}
}).subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<T>() {
@Override
public void call(T value) {
if (resultListener != null) {
resultListener.onResult(value);
}
}
});
}
2、存取實體對象列表,Gson轉換的時候容易出錯,可以特別注意一下:
往列表保存對象,ShareCacheableData是為了獲取對象的唯一標識:
public static final <T extends ShareCacheableData> void putList(final String fileKey, final String valueKey, final Class<T[]> clazz, final T t){
Observable.create(new Observable.OnSubscribe<Object>() {
@Override
public void call(Subscriber<? super Object> subscriber) {
SharedPreferences sp = OpenEyeApplication.getInstance().getSharedPreferences(fileKey,Context.MODE_PRIVATE);
String listJson = sp.getString(valueKey,"");
List<T> oldList = new ArrayList<>();
if (!TextUtils.isEmpty(listJson)){
T[] array = new Gson().fromJson(listJson,clazz);
oldList = new ArrayList<T>(Arrays.asList(array));
}
Iterator<T> iterator = oldList.iterator();
while (iterator.hasNext()){
T item = iterator.next();
if (TextUtils.equals(item.getId(),t.getId())){
iterator.remove();
}
}
oldList.add(t);
SharedPreferences.Editor editor = sp.edit();
editor.putString(valueKey,new Gson().toJson(oldList));
editor.commit();
subscriber.onStart();
}
}).subscribeOn(Schedulers.io()).subscribe();
}
讀取對象列表:
public static final <T extends ShareCacheableData> void getList(final String fileKey, final String valueKey, final Class<T[]> clazz, final SPResultListener<List<T>> resultListener) {
Observable.fromCallable(new Callable<List<T>>() {
@Override
public List<T> call() throws Exception {
SharedPreferences sp = OpenEyeApplication.getInstance().getSharedPreferences(fileKey, Context.MODE_PRIVATE);
String sResult = sp.getString(valueKey, "");
if (TextUtils.isEmpty(sResult)) {
return null;
} else {
T[] list = new Gson().fromJson(sResult, clazz);
return new ArrayList<T>(Arrays.asList(list));
}
}
}).subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<List<T>>() {
@Override
public void call(List<T> value) {
if (resultListener != null) {
resultListener.onResult(value);
}
}
});
}
結束了。。。