[Android] 数据实体的自动存取--SharedPreferences篇

本文介绍了在Android中如何使用SharedPreferences进行数据实体的自动存取,强调了对键值对操作的规范化,并提到了在处理多组数据时命名键的挑战。还预告了下篇将探讨SQLite的数据存取。
摘要由CSDN通过智能技术生成
本例代码以SharedPreferences为数据存取载体。
利用SharedPreferences存取一个数据,步骤如下:
SharedPreferences sharedPre = getSharedPreferences(name, mode);
存:
SharedPreferences.Editor editor = sharedPre.edit();

editor.put(key,value);
editor.commit();
取:
value = sharedPre.get(key,defaultValue);

观察以上,存取的关键是规范好对<key,value>的操作。其中key为字符串为预先定义好的。如果有多组<key,value>,则为每组想好key的名称也是一件挺纠结的事。


本文自动读取的核心在于直接使用数据实体的属性名做为key值,在存取时遍历数据实例的属性,使用反射类读取属性的名称,对属性值进行写出或写入。

本文为Sodino所有,转载请注明出处:http://blog.csdn.net/sodino/article/details/7979559

首先,事先定义好可处理的存取数据类型如下:

	public static final int CLZ_BYTE = 1;
	public static final int CLZ_SHORT = 2;
	public static final int CLZ_INTEGER = 3;
	public static final int CLZ_LONG = 4;
	public static final int CLZ_STRING = 5;
	public static final int CLZ_BOOLEAN = 6;
	public static final int CLZ_FLOAT = 7;
	public static final int CLZ_DOUBLE = 8;
	public static final Map<Class<?>, Integer> TYPES;
	static {
		TYPES = new HashMap<Class<?>, Integer>();
		TYPES.put(byte.class, CLZ_BYTE);
		TYPES.put(short.class, CLZ_SHORT);
		TYPES.put(int.class, CLZ_INTEGER);
		TYPES.put(long.class, CLZ_LONG);
		TYPES.put(String.class, CLZ_STRING);
		TYPES.put(boolean.class, CLZ_BOOLEAN);
		TYPES.put(float.class, CLZ_FLOAT);
		TYPES.put(double.class, CLZ_DOUBLE);
	}

写出:
	private void doSave(GoodsBean bean) {
		SharedPreferences sharedPre = getSharedPreferences(GoodsBean.class.getName(), Context.MODE_PRIVATE);
		SharedPreferences.Editor editor = sharedPre.edit();
		Class<? extends GoodsBean> clazz = bean.getClass();
		Field[] arrFiled = clazz.getDeclaredFields();
		try {
			for (Field f : arrFiled) {
				Log.d("ANDROID_LAB", "type[" + f.getType() + "] name[" + f.getName() + "]");
				int type = TYPES.get(f.getType());
				switch (type) {
				case CLZ_BYTE:
				case CLZ_SHORT:
				case CLZ_INTEGER:
					editor.putInt(f.getName(), f.getInt(bean));
					break;
				case CLZ_LONG:
					editor.putLong(f.getName(), f.getLong(bean));
					break;
				case CLZ_STRING:
					editor.putString(f.getName(), (String) f.get(bean));
					break;
				case CLZ_BOOLEAN:
					editor.putBoolean(f.getName(), f.getBoolean(bean));
					break;
				case CLZ_FLOAT:
					editor.putFloat(f.getName(), f.getFloat(bean));
					break;
				case CLZ_DOUBLE:
					editor.putFloat(f.getName(), (float) f.getDouble(bean));
					break;
				}
			}
			editor.commit();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
	}
读入:
	private GoodsBean doRead() {
		SharedPreferences sharedPre = getSharedPreferences(GoodsBean.class.getName(), Context.MODE_PRIVATE);
		GoodsBean bean = new GoodsBean();
		Class<? extends GoodsBean> clazz = bean.getClass();
		Field[] arrFiled = clazz.getDeclaredFields();
		try {
			for (Field f : arrFiled) {
				int type = TYPES.get(f.getType());
				switch (type) {
				case CLZ_BYTE:
					byte byteValue = (byte) sharedPre.getInt(f.getName(), 0);
					f.set(bean, byteValue);
					break;
				case CLZ_SHORT:
					short shortValue = (short) sharedPre.getInt(f.getName(), 0);
					f.set(bean, shortValue);
					break;
				case CLZ_INTEGER:
					int intValue = sharedPre.getInt(f.getName(), 0);
					f.set(bean, intValue);
					break;
				case CLZ_LONG:
					long longValue = sharedPre.getLong(f.getName(), 0L);
					f.set(bean, longValue);
					break;
				case CLZ_STRING:
					String str = sharedPre.getString(f.getName(), null);
					f.set(bean, str);
					break;
				case CLZ_BOOLEAN:
					boolean bool = sharedPre.getBoolean(f.getName(), false);
					f.set(bean, bool);
					break;
				case CLZ_FLOAT:
					float floatValue = sharedPre.getFloat(f.getName(), 0.0f);
					f.set(bean, floatValue);
					break;
				case CLZ_DOUBLE:
					double doubleValue = sharedPre.getFloat(f.getName(), 0.0f);
					f.set(bean, doubleValue);
					break;
				}
			}
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
		return bean;
	}

GoodsBean.java

package lab.sodino.autosave;

public class GoodsBean {
	public String name;
	public long time;
	public int price;
	public boolean isPaid;
	/** 测试用。 */
	public byte testByte;
	/** 测试用。 */
	public short testShort;
	public float cicle;
	public double testDouble;

	public String toString() {
		StringBuffer strBuffer = new StringBuffer();
		strBuffer.append("name[" + name + "]\n");
		strBuffer.append("time[" + time + "]\n");
		strBuffer.append("price[" + price + "]\n");
		strBuffer.append("isPaid[" + isPaid + "]\n");
		strBuffer.append("cicle[" + cicle + "]\n");
		strBuffer.append("testByte[" + testByte + "]\n");
		strBuffer.append("testShort[" + testShort + "]\n");
		strBuffer.append("testDouble[" + testDouble + "]\n");
		return strBuffer.toString();
	}

	public static GoodsBean newInstance() {
		GoodsBean bean = new GoodsBean();
		bean.name = "AutoSave";
		bean.time = 12345234252342l;
		bean.price = 1024;
		bean.isPaid = true;
		bean.cicle = 2.356f;
		bean.testByte = 8;
		bean.testShort = 128;
		bean.testDouble = 9856.2145d;
		return bean;
	}
}


注意事项如下:
1.由于 SharedPreferences默认仅支持int/long/boolean/string/float 5种数据类型的读写,所以有一些强制转换的操作。由01.gif可看出对double的存取操作会导致数据失真。在实际编码工作中应注意些现象。如下图:

2.需要处理好初始默认值。

自动存取的优点:
1.避免给一大堆key起名字,减少纠结时间。
2.方便、高效。数据结构的改变不需要重新修改存取过程。
3.出混淆包后,所有的key值也随着一起混淆了,在一定程度上保护了程序逻辑。见图01.png

缺点:
1.自动存取会将定义的数据结构全部存或全部取。如果想增加一些不需要本地存储的属性,则需要另建新类继承原有数据结构才得以实现。

有利有弊,但总的来说利远大于弊。

下篇:[Android] 数据实体的自动存取--SQLite篇




评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值