SharedPreferences的使用三

       上一节我们学习了如何对SharedPreferences的数据进行增删改查,由上一节我们可以知道SharedPreferences只能保存int、long、float、boolean、string和string的set集合,如果我们想要保存一个可序列化对象怎么办呢?要保存一个可序列化对象的集合又怎么办呢?同样如果要保存一个字节数组怎么办?以及其他类型的数组怎么办?接下来我们一一解决这些问题。

      首先解决字节数组,一个思路就是将字节数组转化为string类型在保存为string,字节数组转string很简单就不写了,接下来解决可序列化对象保存问题,思路就是先将可序列化对象转化为字节数组,在用字节数组的保存方法保存,下面是可序列化对象转字节数组的方法

  public byte[] putSerializable(String key, Serializable serializable) {
        byte[] buff= null;
        try {
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(bos);
            oos.writeObject(serializable);
            buff=bos.toByteArray();
            StreamUtil.close(oos);//关闭数据流
            StreamUtil.close(bos);//关闭数据流
        } catch (Exception e) {
            e.printStackTrace();
        }
        return buff;
    }

        其他的问题也可以用相应的办法解决,这里就不一一介绍了,我们会发现全都转化到string类型保存的,这样就引入了一个新问题就是如何区分是string类型还是其他类型呢,用系统自带的是不好区分了,下面我们就自己编写一个SharedPreferences,先看代码

public class SharedPreferences {
	List<Entry> entries;//节点
	private File mFile;//文件
	private DocumentBuilder documentBuilder;//dom解析器,可以替换成别的

	public SharedPreferences(File file) {
		// TODO Auto-generated constructor stub
		if (NullUtil.isEmpty(file))
			throw new NullPointerException("file is null");
		mFile = file;
		entries = new ArrayList<>();
		try {
			documentBuilder = DocumentBuilderFactory.newInstance()
					.newDocumentBuilder();
		} catch (Exception e) {
			// TODO Auto-generated catch block
		}
		if (file.exists()) {
			if (file.isDirectory())
				throw new RuntimeException("file is directory");
			paras();
		}

	}

	private void paras() {
		// TODO Auto-generated method stub
		InputStream is = FileUtil.file2inputStream(mFile);
		if (NullUtil.isEmpty(is))
			return;
		try {
			Document document = documentBuilder.parse(is);
			NodeList list = document.getChildNodes();
			if (NullUtil.isEmpty(list))
				return;
			list = list.item(0).getChildNodes();
			if (NullUtil.isEmpty(list))
				return;
			int len = list.getLength();
			for (int i = 0; i < len; i++) {
				Node node = list.item(i);
				Entry entry = paras(node);
				if (NullUtil.isEmpty(entry))
					continue;
				entries.add(entry);
			}
		} catch (Exception e) {
			// TODO: handle exception
		} finally {
			StreamUtil.close(is);
		}
	}
   //将节点转化为节点对象
	private Entry paras(Node node) {
		// TODO Auto-generated method stub
		try {
			String type = node.getNodeName();//标签名,也是类型名
			if ("#text".equals(type))//去掉#text节点
				return null;
			NamedNodeMap map = node.getAttributes();
			String key = map.getNamedItem("key").getTextContent().trim();//获取键
			String value = node.getTextContent();//获取值
			System.out.println(key + "  " + type + "  " + value);
			if ("string".equals(type))//string类型
				return new Entry(type, key, value);
			if ("int".equals(type))//int类型
				return new Entry(type, key, Integer.valueOf(value));
			if ("boolean".equals(type))//boolean类型
				return new Entry(type, key, Boolean.valueOf(value));
			if ("float".equals(type))//float类型
				return new Entry(type, key, Float.valueOf(value));
			if ("long".equals(type))//long类型
				return new Entry(type, key, Long.valueOf(value));
			if ("double".equals(type))//double类型
				return new Entry(type, key, Double.valueOf(value));
			if ("set".equals(type)) {//set类型(set集合中可以放其他类型,不一定是string类型,需要去完善下)
				NodeList list = node.getChildNodes();
				if (NullUtil.isEmpty(list) && list.getLength() <= 0)
					return new Entry(type, key, null);
				int len = list.getLength();
				Set<String> set = new HashSet<String>(len);
				for (int i = 0; i < len; i++) {
					node = list.item(i);
					set.add(node.getTextContent().toString().trim());
				}
				return new Entry(type, key, set);
			}
			throw new RuntimeException("标签出错了");
		} catch (Exception e) {
			// TODO: handle exception
		}
		return null;
	}

	public String getString(String key, String defValue) {
		Entry entry = serch(key);
		if (NullUtil.isEmpty(entry))
			return defValue;
		if ("string".equals(entry.type))
			return (String) entry.value;
		return defValue;
	}

	public int getInt(String key, int defValue) {
		Entry entry = serch(key);
		if (NullUtil.isEmpty(entry))
			return defValue;
		if ("int".equals(entry.type))
			return (int) entry.value;
		return defValue;
	}

	public long getLong(String key, long defValue) {
		Entry entry = serch(key);
		if (NullUtil.isEmpty(entry))
			return defValue;
		if ("long".equals(entry.type))
			return (long) entry.value;
		return defValue;
	}

	public float getFloat(String key, float defValue) {
		Entry entry = serch(key);
		if (NullUtil.isEmpty(entry))
			return defValue;
		if ("float".equals(entry.type))
			return (float) entry.value;
		return defValue;
	}

	public boolean getBoolean(String key, boolean defValue) {
		Entry entry = serch(key);
		if (NullUtil.isEmpty(entry))
			return defValue;
		if ("boolean".equals(entry.type))
			return (boolean) entry.value;
		return defValue;
	}

	public double getDouble(String key, double defValue) {
		Entry entry = serch(key);
		if (NullUtil.isEmpty(entry))
			return defValue;
		if ("double".equals(entry.type))
			return (double) entry.value;
		return defValue;
	}

	@SuppressWarnings("unchecked")
	public Set<String> getSet(String key, Set<String> defValue) {
		Entry entry = serch(key);
		if (NullUtil.isEmpty(entry))
			return defValue;
		if ("set".equals(entry.type))
			return (Set<String>) entry.value;
		return defValue;
	}

	public boolean contains(String key) {
		int index = indexOf(key);
		return index > -1;
	}

	public SharedPreferences putString(String key, String value) {
		entries.add(new Entry("string", key, value));
		return this;
	}

	public SharedPreferences putInt(String key, int value) {
		entries.add(new Entry("int", key, value));
		return this;
	}

	public SharedPreferences putLong(String key, long value) {
		entries.add(new Entry("long", key, value));
		return this;
	}

	public SharedPreferences putFloat(String key, float value) {
		entries.add(new Entry("float", key, value));
		return this;
	}

	public SharedPreferences putBoolean(String key, boolean value) {
		entries.add(new Entry("boolean", key, value));
		return this;
	}

	public SharedPreferences putDouble(String key, double value) {
		entries.add(new Entry("double", key, value));
		return this;
	}

	public SharedPreferences putSet(String key, Set<String> value) {
		entries.add(new Entry("set", key, value));
		return this;
	}

	public SharedPreferences remove(String key) {
		int index = indexOf(key);
		if (index > -1)
			entries.remove(index);
		return this;
	}

	public SharedPreferences clear() {
		entries.clear();
		return this;
	}

	private int indexOf(String key) {
		if (NullUtil.isEmpty(entries))
			return -1;
		if (NullUtil.isEmpty(key))
			return -1;
		int len = entries.size();
		for (int i = 0; i < len; i++) {
			if (key.equals(entries.get(i).key))
				return i;
		}
		return -1;
	}

	private Entry serch(String key) {
		int index = indexOf(key);
		return index > -1 ? entries.get(index) : null;
	}

	//提交数据,将数据保存到文件中
	public boolean commit() {
		try {
			if (NullUtil.isEmpty(entries))
				return false;
			TransformerFactory transFactory = TransformerFactory.newInstance();
			Transformer transformer = transFactory.newTransformer();
			transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
			transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //
			transformer
					.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
			FileWriter fileWriter = new FileWriter(mFile);
			Result result = new StreamResult(fileWriter);
			Document document = documentBuilder.newDocument();
			Iterator<Entry> iterator = entries.iterator();
			Element element = document.createElement("map");
			document.appendChild(element);
			while (iterator.hasNext()) {
				Entry entry = iterator.next();
				if ("set".equals(entry.type)) {
					Element setElement = document.createElement(entry.type);
					element.setAttribute("key", entry.key);
					Set<String> valueSet = (Set<String>) entry.value;
					if (!NullUtil.isEmpty(valueSet)) {
						for (String string : valueSet) {
							Element setValue = document.createElement("value");
							setValue.setTextContent(string);
							setElement.appendChild(setValue);
						}
					}
				} else
					element.appendChild(entry2node(document, entry));
			}
			transformer.transform(new DOMSource(document), result);
			StreamUtil.close(fileWriter);
			return true;
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
		return false;
	}

	private Node entry2node(Document document, Entry entry) {
		// TODO Auto-generated method stub
		Element element = document.createElement(entry.type);
		element.setTextContent(entry.value.toString());
		element.setAttribute("key", entry.key);
		return element;
	}

	private class Entry {
		String type;// int,long,float,boolean,string,set等,自己可以在添加
		String key;//保存的键
		Object value;//保存的值

		public Entry(String type, String key, Object object) {
			// TODO Auto-generated constructor stub
			this.type = type;
			this.value = object;
			this.key = key;
		}

	}
}

通过上面我们发现我们用类型作为标签名,key是属性,value是值,这样我们就可以区分类型了,上面只是模仿了系统的SharedPreferences,如果需要保存其他类型或其他类型的集合,就需要对这个类稍微修改下,重点是修改解析和保存方法。这样就解决了上面提到的问题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值