SharedPreferences,使用base64编码,保存复杂对象

本文介绍Base64编码原理及应用,重点讲解如何利用Base64编码方式将复杂对象存储到SharedPreferences中,包括序列化、编码及解码过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

SharedPreferences 使用base64保存复杂对象

本篇博文建议电脑看,因为要对应码表

什么是base64:

base64是编码方式之一

什么是编码方式(base64):

编码方式是信息从一种格式转换为另一种格式的过程
看到比较的多编码方式有:ASCII,GBK,Unicode…

base64是为了解决什么而出现的:

通俗的说就是以前的邮件网络传送,只能传送我们肉眼看到的字符,而看不到的字符不可以发送,
比如换行符啊,空格,回车。为了解决传送不了这些不可见字符,所以就出现了base64编码方式。

我对base64的通俗理解:

base64其实就是使用了64个肉眼可以看到的字符来表示二进制,而计算中的数据都是使用二进制表示
通俗的说:就是使用64个看的到的字符表示了所有数据:包括肉眼可见的和肉眼不可见的

base64的64个字符是啥:(看图,来自维基百科:https://en.wikipedia.org/wiki/Base64)
可以看到value是0-63,char是"A-Z、a-z、0-9" 一个加号和一个斜杆(刚好总共64个)
这里写图片描述

我理解的索引表(base64):
索引表都是约定俗成的,固定的value表示固定的char,就好像加法表一样,1+1=2,这个是固定的了,解析不了为啥,比如:1+1=2

字节和位(base64)

我们都知道一个字节等于八位。而想表示base64索引表中的value:0-63,要多少字节呢,答案:不需要一个字节(8位),只需要6位就可以表示,
十进制的0-63只要二进制的111111(6位)就可以表示玩了

00000000 转换为10进制 0
00111111 转换为10进制 63

如何转换为base64

字符串转为base64码,需要把字符转为ascll码中的数字,然后再把数字转换为二进制,然后再转base64

ASCII对照表(如果是直接输入,然后查询的,有的是错的(2018/6/5),还是肉眼慢慢找吧) http://ascii.911cha.com/
这里写图片描述

这里写图片描述

下面来一些例子:

首先是我的名字:

字符串: l i n x i n

ASCII 108 105 110 120 105 110
二进制8位 0110 1100 0110 1001 0110 1110 0111 1000 0110 1001 0110 1110
011011000110100101101110011110000110100101101110
6位 011011 000110 100101 101110 011110 000110 100101 101110
十进制 27 6 37 46 30 6 37 46
对应编码 b G l u e G l u

这里格式不好排,我上传一张图片
这里写图片描述
啊哈哈,对着这些数字找对应编码的时候,让我想起了国民党打仗发的电报(好像也是有一本这样的索引表)


 //通过base64保存复杂对象到SharedPreferences
 public static boolean saveObject(String key, Object obj, Context context) {
        //如果对象为null,不保存,直接返回保存失败
        if (obj == null) {
            return false;
        }
        //flag,用于判断是否保存对象成功
        boolean flag = false;
        SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
        // 内部创建一个byte型别数组的缓冲区,最初默认为32位,在需要的时候会自动增加大小,从流中读字节数组
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        //主要的作用是用于写入对象信息与读取对象信息
        ObjectOutputStream objectOutputStream = null;
        try {
            // 创建对象输出流,并封装字节流
            objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
            // 将对象写入字节流
            objectOutputStream.writeObject(obj);
            // 将字节流编码成base64的字符窜
            String base64String = new String(Base64.encode(byteArrayOutputStream
                    .toByteArray(), Base64.DEFAULT));
            flag = preferences.edit().putString(key, base64String).commit();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //主要做关闭流操作
            try {
                if (objectOutputStream != null) {
                    objectOutputStream.close();
                }
                if (byteArrayOutputStream != null) {
                    byteArrayOutputStream.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return flag;
        }
    }
//读取复杂对象
    public static Object getObject(String key, Context context) {
        Object obj = null;
        SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
        String objString = preferences.getString(key, "");
        // 读取字节
        byte[] base64 = Base64.decode(objString.getBytes(), Base64.DEFAULT);
        // 字节流
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(base64);
        //对象流
        ObjectInputStream objectInputStream = null;
        try {
            // 再次封装
            objectInputStream = new ObjectInputStream(byteArrayInputStream);
            // 读取对象
            obj = objectInputStream.readObject();
        } catch (Exception e) {
            // e.printStackTrace();
        } finally {
            try {
                if (objectInputStream != null) {
                    objectInputStream.close();
                }

                if (byteArrayInputStream != null) {
                    byteArrayInputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return obj;
    }


//序列化的实体类
class Person implements Serializable {
    private String firstName;
    private String lastName;

    public Person(String firstName, String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }

    @Override
    public String toString() {
        return lastName+firstName;
    }
}
//简单用例
public class MainActivity extends AppCompatActivity {

    private static final String KEY = "key";
    private static final String TAG = "MainActivity";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Person p = new Person("lin", "xin");
        if (saveObject(KEY, p, this)) {
            Log.i(TAG, getObject(KEY, this).toString());
        } else {
            Log.i(TAG, "onCreate:失败 ");
        }
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值