Android中雖然提供了SharedPreference類方便的對配置文件進行操作。但是好用嗎?
假如有成百上千的參數需要存儲,這樣一個個分散的寫法累死個人啊。本來幾分鐘能搞定的活,你可能得幾個鐘頭。效率能是一個等級?且到處分散的寫法,也容易讓人看暈,給維護造成困難。
先來看結果:
原來的使用方式是這樣的:
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
//讀取存儲的IP和端口
String ip = sp.getInt("IP", "127.0.0.1");
int port = sp.getString("PORT",5050);
//保存IP和端口
ip = "218.28.111.121";
sp.putString("IP",ip)
如果參數少還無所謂,如果需要用到的參數很多,且到處都是。這種用法豈不是太混亂,太繁瑣?
來看看原來的這種有多恐怖,
再來出一道題,假如我有一套票價參數要存儲,每種卡類型有卡類型,折扣,提示信息等參數需要存儲。讓你用SharedPreferences去存儲,你會怎麼做?
先看下c語言裏結構體票價參數的定義,讓用Android的SharedPreferences怎麼辦?
即便不使用SharedPreferences,使用文件的方式存爲json或xml或ini或yaml,哪個都不是那麼簡單好用。
如果參數很多,累死個人了,很容易漏了或忘了賦值導致參數沒存儲。且沒有全局管理意識的人會到處使用。導致你甚至不知道到底存儲了哪些東東,哪些是存儲了,哪些是沒存儲的。只能費勁兒的找,搜索,CTRL+F...
再來看看這種方式:
syscfg.ip = "218.28.133.181";
syscfg.port = 22288;
syscfg.saveCfg();
Log.d(TAG,syscfg.toString());
dealCfg.ver = 12;
dealCfg.time = "201910251551";
dealCfg.discInfo[0].cardType = 5;
dealCfg.discInfo[0].purseDisc = 100;
dealCfg.discInfo[1].cardType = 6;
dealCfg.discInfo[1].purseDisc = 200;
dealCfg.saveCfg();
可以看到實現後使用是多麼的簡單直觀。開機後先load一次從配置文件加載到成員變量中。
後續隨便使用和賦值。想要保存,直接調用save()即可。且跟配置相關的參數都在全局的一個SysCfg中,
還害怕漏了或找不到嗎?按這樣封裝好後,即便不會Android存儲的人,也會清爽使用。
//跟系統參數相關的所有參數配置和存儲
Class SysCfg{
String ip;
int port;
void load(){
...
}
void save(){
//自動把ip,port的內容存儲起來
for(...){
put("ip",value)
...
}
static void main(String[] args){
SysCfg cfg = new SysCfg();
cfg.load()//加載配置文件中的參數到成員變量中
cfg.ip = "127.0.0.1"; //賦值
cfg.port= 5050;
cfg.save();//自動持久化存儲了SysCfg的所有參數
}
}
最後,封裝實現的代碼分享一下,使用註解+反射讓配置文件操作如此清晰和簡單。
所有需要用到的參數,定義在一個繼承自Configer的類中即可。
package com.newcapec.b601.config;
import android.content.Context;
import java.lang.reflect.Field;
/**
* Android存儲的封裝
* Author:yangyongzhen
* QQ:534117529
*/
public class Configer {
public static final String TAG = "Configer"; //做爲配置文件的文件名
private SharedPreferencesHelper helper;
//===========================================================
public Configer(Context cx,String name){
helper = new SharedPreferencesHelper(cx,name);
}
/**
* 自動完成所有帶有Save註解的成員變量的存儲
*/
public int saveCfg(){
Class cls = this.getClass();
Field[] fields = cls.getDeclaredFields();
for(Field field :fields) {
if (field.isAnnotationPresent(Save.class)) {
try {
Save sa = (Save) field.getAnnotation(Save.class);
String key = sa.value();
String val = (String) helper.get(key,"");
Object obj = field.get(this);
if(obj.equals(val)){
continue;
}
if(obj instanceof String) {
helper.put(key,obj);
}else if(obj instanceof Integer){
helper.put(key,obj);
}
} catch (IllegalAccessException e) {
e.printStackTrace();
return 1;
}
}
}
return 0;
}
/**
* 自動完成所有帶有Save註解的成員變量的加載
* @return
*/
public int openCfg(){
Class cls = this.getClass();
Field[] fields = cls.getDeclaredFields();
for(Field field :fields) {
if (field.isAnnotationPresent(Save.class)) {
try {
Save sa = (Save) field.getAnnotation(Save.class);
String key = sa.value();
if(field.get(this) instanceof String) {
String val = (String) helper.get(key,"");
field.set(this,val);
}else if(field.get(this) instanceof Integer){
Integer val = (Integer) helper.get(key,0);
field.set(this,val);
}
} catch (IllegalAccessException e) {
e.printStackTrace();
return 1;
}
}
}
return 0;
}
}
Save的註解也很簡單:
package com.newcapec.testsqllite.config;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(value = {ElementType.FIELD})
@Retention(value = RetentionPolicy.RUNTIME)
public @interface Save {
String value();
}
使用方式:
package com.newcapec.b601.config;
import android.content.Context;
public class SysCfg extends Configer {
public static final String TAG = "SysCfg"; //做爲配置文件的文件名
private static SysCfg _instance = null;
private SysCfg(Context cx,String name) {
super(cx,name);
}
//========================================================
//IP地址
//(需要持久化存儲的,加上Save註解即可)
@Save("ip")
public String ip = "127.0.0.1";
//服務器端口
@Save("port")
public Integer port = 999;
public Integer port1 = 1000;
@Override
public String toString() {
return "Sys{" +
"ip='" + ip + '\'' +
", port=" + port +
", port1=" + port1 +
'}';
}
public static SysCfg getInstance(Context context) {
if (_instance == null) {
synchronized(SysCfg.class){
if (_instance == null) {
_instance = new SysCfg(context,TAG);
}
}
}
return _instance;
}
}
syscfg.ip = "218.28.133.181";
syscfg.port = 22288;
syscfg.saveCfg();
Log.d(TAG,syscfg.toString());
dealCfg.ver = 12;
dealCfg.time = "201910251551";
dealCfg.discInfo[0].cardType = 5;
dealCfg.discInfo[0].purseDisc = 100;
dealCfg.discInfo[1].cardType = 6;
dealCfg.discInfo[1].purseDisc = 200;
dealCfg.saveCfg();