zoukankan      html  css  js  c++  java
  • 数据存储(一)--SharedPreferences之你不知道的事

    一、SharedPreferences将数据文件保存在指定路径上

    SharedPreferences原则上是仅仅能保存在当前应用程序私有的shared_prefs文件夹中,只是也不是绝对的,我们能够用一些非常规的方法改变存储文件夹,反射技术是非常好的选择。

    先上实现代码:

    private  SharedPreferences share;
    private  SharedPreferences.Editor editor;

    改动路径关键代码:

    private void initSharedPreferences(String path,String name,int mode)
    	{
    		try {
    	 		Field field =ContextWrapper.class.getDeclaredField("mBase");
    			field.setAccessible(true);
    			Object obj = field.get(this);
    			field = obj.getClass().getDeclaredField("mPreferencesDir");
    			field.setAccessible(true);
    			File file = new File(path);
    			field.set(obj, file);
    			share = getSharedPreferences(name, mode);
    			editor = share.edit();
    		} catch (Exception e) {
    			// TODO: handle exception
    			e.printStackTrace();
    		}
    	}
    Field field =ContextWrapper.class.getDeclaredField("mBase");
    获取ContextWrapper对象中的mBase变量,该变量保存了ContextImpl对象,ContextImpl对象中的mPreferencesDir保存了数据文件的保存路径。

    share = getSharedPreferences(name, mode);
    运行这句后会在指定文件夹下创建文件用来保存数据。


    PS:使用反射技术,要求细致研究源代码,这样才会知道要去改动哪个地方,哪个变量。

    使用:

    		initSharedPreferences("/data/fly","config",Activity.MODE_PRIVATE);
    		editor.putString("AA", "AAaa");
    		editor.commit();
    		Toast.makeText(this, share.getString("AA", ""), 1000).show();



    二、SharedPreferences保存图片

    SharedPreferences原则上仅仅能将字符串以key-value的形式保存,可是我们能够採用编码的方式将不论什么二进制数据转化为字符串。从而将能够将二进制数据保存在SharedPreferences文件里。最经常使用的编码格式是Base64.

    private void saveDrawable(int id)
        {
            Bitmap bitmap = BitmapFactory.decodeResource(getResources(), id);
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            bitmap.compress(CompressFormat.JPEG, 50, baos);
            String imageBase64 = new String(Base64.encodeToString(baos.toByteArray(),Base64.DEFAULT));
            editor.putString("P",imageBase64 );
            editor.commit();
        }
        
        private Drawable loadDrawable()
        {
            String temp = share.getString("P", "");
            ByteArrayInputStream bais = new ByteArrayInputStream(Base64.decode(temp.getBytes(), Base64.DEFAULT));
            return Drawable.createFromStream(bais, "");
        }


    三、SharedPreferences保存对象

    因为二进制数据经过编码后能够用SharedPreferences以字符串的形式存储。所以保存对象也称为可能。

    private void saveProduct(Product product)
    	{
    		ByteArrayOutputStream baos = new ByteArrayOutputStream();
    		try {
    			ObjectOutputStream oos = new ObjectOutputStream(baos);
    			oos.writeObject(product);
    			String temp = new String(Base64.encode(baos.toByteArray(), Base64.DEFAULT));
    			Log.i("AAA", temp);
    			editor.putString("product", temp);
    			editor.commit();
    		} catch (IOException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    	}
    	
    	private Product getProduct()
    	{
    		String temp = share.getString("product", "");
    		ByteArrayInputStream bais =  new ByteArrayInputStream(Base64.decode(temp.getBytes(), Base64.DEFAULT));
    		Product product = null;
    		try {
    			ObjectInputStream ois = new ObjectInputStream(bais);
    			product = (Product) ois.readObject();
    		} catch (IOException e) {
    			// TODO Auto-generated catch block
    			Log.i("AAA", e.toString());
    		}catch(ClassNotFoundException e1)
    		{
    			Log.i("AAA", e1.toString());
    		}
    		return product;
    	}

    对象能够被SharedPreferences存储的前提是该对象被序列化了,也就是说要实现Serializable接口,实际上Serializable接口是个空接口,仅仅是为了标记该对象是被序列化的。

    public static class Product implements Serializable
    	{
    		String name;
    		String id;
    		int count;
    		public String getName() {
    			return name;
    		}
    		public void setName(String name) {
    			this.name = name;
    		}
    		public String getId() {
    			return id;
    		}
    		public void setId(String id) {
    			this.id = id;
    		}
    		public int getCount() {
    			return count;
    		}
    		public void setCount(int count) {
    			this.count = count;
    		}
    		
    		public String toString()
    		{
    			return "name:"+name+" id:"+id+" count:"+count;
    		}
    
    	}

    假设该类是内部类的话要写成static 不然会出现java.io.NotSerializableException异常:解决的方法点这里

  • 相关阅读:
    Windows Azure Storage (17) Azure Storage读取访问地域冗余(Read Access – Geo Redundant Storage, RA-GRS)
    SQL Azure (15) SQL Azure 新的规格
    Azure China (5) 管理Azure China Powershell
    Azure China (4) 管理Azure China Storage Account
    Azure China (3) 使用Visual Studio 2013证书发布Cloud Service至Azure China
    Azure China (2) Azure China管理界面初探
    Azure China (1) Azure公有云落地中国
    SQL Azure (14) 将云端SQL Azure中的数据库备份到本地SQL Server
    [New Portal]Windows Azure Virtual Machine (23) 使用Storage Space,提高Virtual Machine磁盘的IOPS
    Android数据库升级、降级、创建(onCreate() onUpgrade() onDowngrade())的注意点
  • 原文地址:https://www.cnblogs.com/lcchuguo/p/5313972.html
Copyright © 2011-2022 走看看