用户列表List保存到SP文件

SharePreference 提供了getSet,putSet方法来存储集合类,但是在3.0以前的版本都不支持,而且即使3.0以后的系统版本也有可能会报错:No such method

先写一个demo的实现

1 工具类 SharedPreSetUtil
package com.bj.jack.muluserinfosave.util;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.io.StreamCorruptedException;
import java.util.ArrayList;
import java.util.List;

import com.bj.jack.muluserinfosave.dto.UserInfo;

import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.util.Base64;

public class SharedPreSetUtil {

    public final static String KEY_NAME = "KEY_NAME";

    private static SharedPreSetUtil instance;

    private SharedPreferences msp;

    public static SharedPreSetUtil getInstance(Context context) {
        if (instance == null) {
            instance = new SharedPreSetUtil(context);
        }
        return instance;
    };

    private SharedPreSetUtil(Context context) {
        msp = context.getSharedPreferences("LOGINUSERLIST", Context.MODE_PRIVATE);
    }

    @SuppressWarnings("unchecked")
    public void putUsers(UserName user) {
        Editor editor = msp.edit();
        String str = "";
        try {
            List<UserName> list = new ArrayList<UserName>();
            //之前的记录
            if(getUserInfos()!=null){
                list.addAll(getUserInfos());
            }
            list.add(user);
            str = list2String(list);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        editor.putString(SharedPreSetUtil.KEY_NAME, str);
        editor.commit();
    }

    public List<UserName> getUserInfos() {
        List<UserName> users = new ArrayList<UserName>();
        String str = msp.getString(SharedPreSetUtil.KEY_NAME, "");
        try {
            final List<UserName> objs = string2List(str);
            if (objs != null) {
                UserName user;
                for (int i = 0; i < objs.size(); i++) {
                    user = (UserName) (objs.get(i));
                    users.add(user);
                }
            }
        } catch (StreamCorruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return users;
    }

    public String list2String(List<UserName> list) throws IOException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(baos);
        oos.writeObject(list);
        String listString = new String(Base64.encode(baos.toByteArray(),Base64.DEFAULT));
        oos.close();
        return listString;
    }

    public List<UserName> string2List(String str)
            throws StreamCorruptedException, IOException {
        byte[] mByte = Base64.decode(str.getBytes(), Base64.DEFAULT);
        ByteArrayInputStream bais = new ByteArrayInputStream(mByte);
        ObjectInputStream ois = new ObjectInputStream(bais);
        List<UserName> stringList = null;
        try {
            stringList = (List<UserName>) ois.readObject();
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return stringList;
    }


    public void deleteUser(List<UserName> users){
    Editor editor = msp.edit();
    editor.remove(SharedPreSetUtil.KEY_NAME);
    editor.commit();

    String str = "";
    try {
        str = list2String(users);
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    editor.putString(SharedPreSetUtil.KEY_NAME, str);
    editor.commit();

}


    public static class UserName implements Serializable {
        private static final long serialVersionUID = 6354789450649564174L;

        private String mUserName;

        public String getmUserName() {
            return mUserName;
        }

        public void setmUserName(String mUserName) {
            this.mUserName = mUserName;
        }
    }
}
2 工具调用

1 添加记录

public void add(View v){
    UserName userInfo = new UserName();
    if(TextUtils.isEmpty(mName.getText())){
        return;
    }else{
        userInfo.setmUserName(mName.getText().toString());
    }
    SharedPreSetUtil.getInstance(this).putUsers(userInfo);
    userInfo = null;
}

2 得到所有记录

public void list(View v){
        //SharedPreUtil sharedPreUtil = new SharedPreUtil(this);
        List<UserName> userInfors = SharedPreSetUtil.getInstance(this).getUserInfos();
        StringBuilder buidler = new StringBuilder();
        if(userInfors!=null&&userInfors.size()>0){
            for(int i=0;i<userInfors.size();i++){
                buidler.append(userInfors.get(i).getmUserName()).append("\n");
            }
        }
        mNameList.setText(buidler.toString());
    }

3 删除记录,相当于另存一个集合

mList.remove(position);
                SharedPreSetUtil.getInstance(mContext).deleteUser(mList);
                mList = SharedPreSetUtil.getInstance(mContext).getUserInfos();
                notifyDataSetChanged();

分析实现

鉴于友盟统计出来的sp中对集合的操作不能支持所有机型的问题,采用对象的序列化以字符串的形式保存到sp中的实现。

先了解一些类方法

  • ByteArrayOutputStream

参照JDK记载

public class ByteArrayOutputStream  extends OutputStream

此类实现了一个输出流,数据被写入到byte数组中。缓冲区会随着数据的不断增长而自动扩展。使用toByteArray和toString获取数据。常用于存储数据执行一次性写入。

    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    baos.close();
    baos.flush();
    baos.size();

该类的方法在关闭流后仍可使用,并且不会发生IO异常。

看一个文件复制的demo

ByteArrayOutputStream baos = new ByteArrayOutputStream();
        String path = Environment.getExternalStorageDirectory().getAbsolutePath()+File.separator+"log.txt";
        File file = new File(path);
        /*FileReader fr = new FileReader(file);
        BufferedReader buffer = new BufferedReader(fr);
        StringBuilder builder = new StringBuilder();
        int len = 0;
        char[] buf = new char[1];
        while((len=buffer.read(buf))!=-1){
            builder.append(buf);
        }*/

        FileInputStream fis = new FileInputStream(file);
        byte[] buffer = new byte[100];
        int len=-1;
        while((len=fis.read(buffer))!=-1){
            //多了会有脏数据
            baos.write(buffer, 0, len);
        }
        baos.flush();
        OutputStream os = new FileOutputStream(Environment.getExternalStorageDirectory().getAbsolutePath()+File.separator+"log2.txt");
        os.write(baos.toByteArray());
        os.flush();
        os.close();

- ObjectOutputStream

ObjectOutputStream与ObjectOutputSteam类所读写的对象必须实现Serializable接口,对象中的transient和static类型的成员变量不会被读取和写入(static不允许被读入,transient是无法获取正确值)。

序列化工具

单一对象和集合对象在当做对象处理时是一样的:保存的时候集合转换为一个较长的String,当做“一个对象”存储“;读取的时候认为读取的是”一个较长的字符“,然后强转为集合对象。

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.StreamCorruptedException;
import java.util.List;
import android.util.Base64;

public class SerializableUtil {
public static <E> String list2String(List<E> list) throws IOException {
    // 实例化一个ByteArrayOutputStream对象,用来装载压缩后的字节文件
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    // 然后将得到的字符数据装载到ObjectOutputStream
    ObjectOutputStream oos = new ObjectOutputStream(baos);
    // writeObject 方法负责写入特定类的对象的状态,以便相应的readObject可以还原它
    oos.writeObject(list);
    // 最后,用Base64.encode将字节文件转换成Base64编码,并以String形式保存
    String listString = new String(Base64.encode(baos.toByteArray(),
            Base64.DEFAULT));
    // 关闭oos
    oos.close();
    return listString;
}

public static String obj2Str(Object obj) throws IOException {
    if (obj == null) {
        return "";
    }
    // 实例化一个ByteArrayOutputStream对象,用来装载压缩后的字节文件
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    // 然后将得到的字符数据装载到ObjectOutputStream
    ObjectOutputStream oos = new ObjectOutputStream(baos);
    // writeObject 方法负责写入特定类的对象的状态,以便相应的readObject可以还原它
    oos.writeObject(obj);
    // 最后,用Base64.encode将字节文件转换成Base64编码,并以String形式保存
    String listString = new String(Base64.encode(baos.toByteArray(),
            Base64.DEFAULT));
    // 关闭oos
    oos.close();
    return listString;
}

// 将序列化的数据还原成Object
public static Object str2Obj(String str) throws StreamCorruptedException,
        IOException {
    byte[] mByte = Base64.decode(str.getBytes(), Base64.DEFAULT);
    ByteArrayInputStream bais = new ByteArrayInputStream(mByte);
    ObjectInputStream ois = new ObjectInputStream(bais);

    try {
        return ois.readObject();
    } catch (ClassNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return null;
}

public static <E> List<E> string2List(String str)
        throws StreamCorruptedException, IOException {
    byte[] mByte = Base64.decode(str.getBytes(), Base64.DEFAULT);
    ByteArrayInputStream bais = new ByteArrayInputStream(mByte);
    ObjectInputStream ois = new ObjectInputStream(bais);
    List<E> stringList = null;
    try {
        stringList = (List<E>) ois.readObject();
    } catch (ClassNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return stringList;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值