我本意就是想简化下配置参数的读取和存储。
原来的方式太繁琐了。
比如我存个 IP ,就得单独调 put("ip","127.0.0.1"), 开机时还得先 String ip = get("ip")去加载。
在Android项目应用中,经常会用到读取和保存配置文件。
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)
如果参数少还无所谓,如果需要用到的参数很多,且到处都是。这种用法岂不是太混乱,太繁琐?
如果参数很多,累死个人了,很容易漏了或忘了赋值导致参数没存储。且没有全局管理意识的人会到处使用。导致你甚至不知道到底存储了哪些东东,哪些是存储了,哪些是没存储的。只能费劲儿的找,搜索,CTRL+F...
而我想要的效果是,所有参数都在一个类文件里定义,看起来很直观。需要存储时只要调用save()方法即可。
理想的样子是这样的:
//跟系统参数相关的所有参数配置和存储 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的所有参数 } }
这样的话,使用起来多么的清晰直观啊!
之前用了一个笨方法,也算是实现了。但是还是使用起来还是不够精简。
参见:https://blog.csdn.net/yyz_1987/article/details/81414274
接下来将用java的注解和反射机制重新实现。
可以看到实现后使用是多么的简单直观。开机后先load一次从配置文件加载到成员变量中。
后续随便使用和赋值。想要保存,直接调用save()即可。且跟配置相关的参数都在全局的一个SysCfg中,
还害怕漏了或找不到吗?按这样封装好后,即便不会Android存储的人,也会清爽使用。
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();
以下为注解加反射机制实现:
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; } }
package com.newcapec.b601.config; import android.content.Context; import java.util.Arrays; public class DealCfg extends Configer { public static final String TAG = "DealCfg"; //做为配置文件的文件名 private static DealCfg _instance = null; public static final int MAX_DISCINFO = 25; private DealCfg(Context cx, String name) { super(cx,name); discInfo = new DiscInfo[MAX_DISCINFO]; for(int i = 0;i < MAX_DISCINFO; i++){ discInfo[i] = new DiscInfo(cx,DiscInfo.TAG+i); } } public class DiscInfo extends Configer{ public static final String TAG = "DiscInfo"; public DiscInfo(Context cx, String name) { super(cx, name); } @Save("cardType") public Integer cardType = 0; @Save("cardStat") public Integer cardStat = 0; @Save("purseDisc") public Integer purseDisc = 0; @Save("audioBuf") public String audioBuf = ""; @Save("disBuf") public String disBuf = ""; @Override public String toString() { return "DiscInfo{" + "cardType=" + cardType + ", cardStat=" + cardStat + ", purseDisc=" + purseDisc + ", audioBuf='" + audioBuf + '\'' + ", disBuf='" + disBuf + '\'' + '}'; } } //======================================================== //版本 //(需要持久化存储的,加上Save注解即可) @Save("ver") public Integer ver = 0; //时间 @Save("time") public String time = ""; public Integer port1 = 1000; @Save("discInfo") public DiscInfo[] discInfo; @Override public int saveCfg() { int ret = 0; ret = super.saveCfg(); if(ret != 0){ return ret; } for(int i = 0;i < MAX_DISCINFO; i++){ ret = discInfo[i].saveCfg(); if(ret != 0){ return ret; } } return ret; } @Override public int openCfg() { int ret; ret = super.openCfg(); if(ret != 0){ return ret; } for(int i = 0;i < MAX_DISCINFO; i++){ ret = discInfo[i].openCfg(); if(ret != 0){ return ret; } } return ret; } public static DealCfg getInstance(Context context) { if (_instance == null) { synchronized(DealCfg.class){ if (_instance == null) { _instance = new DealCfg(context,TAG); } } } return _instance; } @Override public String toString() { return "DealCfg{" + "ver=" + ver + ", time='" + time + '\'' + ", port1=" + port1 + ", discInfo=" + Arrays.toString(discInfo) + '}'; } }