背景
在应用开发过程中,经常会用SharedPreferences存储配置参数、登陆状态等数据。直接使用系统提供的接口虽然能达到目的,但代码太啰嗦。本文目的是要实现一个优雅的SharedPreferences访问接口
目标
- 实现一组简单易用的访问接口
- 支持类型:String, Boolean, boolean, Integer, int, Long, long, Double, double
- 可以通过注解方式配置double类型精度
- 可以通过注解方式配置key,可以是资源文件
- 可以通过注解方式配置默认值,可以是资源文件
设计
接口定义
public interface PreferenceStorage<T> {
boolean isPersistence();
void save(@NonNull T model);
T load();
void clear();
}
Key注解
优先级: resId > key > fieldName
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@Documented
public @interface Key {
String name() default "";
/**
* default key from string resource
*
* @return R.string.xxx
*/
int resId() default 0;
}
默认值注解
优先级: resId > value > defaultValue
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@Documented
public @interface Default {
String value() default "";
/**
* default value from string resource
*
* @return R.string.xxx
*/
int resId() default 0;
}
非字符串字段会进行类型转换
精度注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@Documented
public @interface Precision {
int scale() default 2;
RoundingMode roundingMode() default RoundingMode.HALF_UP;
}
用法
定义数据模型
模型用于跟存储数据建立一对一的映射关系
public class DataModel {
@Ignore
private String ignored;
private String field1;
@Key("field_2")
@Default(resId = R.string.hello)
private String field2;
@Precision
@Default("1.23")
private double field3;
private Double field4;
private Boolean field5;
private boolean field6;
private Integer field7;
private int field8;
private Long field9;
private long field10;
}
定义访问类型
用于存储和加载特定的数据类型
public class DataStore extends AbstractPreferenceStorage<DataModel> {
public DataStore(Context context) {
super(context, "data_model");
}
}
建议使用Application Context
访问数据
// 存储
DataModel model1 = new DataModel();
new DataStore(context).save(model1);
// 加载
DataModel model2 = new DataStore(context).load();
// 清空
new DataStore(context).clear();
实现
依赖
compile 'cn.wrh.android:easy-preference:1.0.0'