SharedPreferences

SharedPreferences用于Android本地存储,使用较简单。SharedPreferences本身是一个接口,它的实现类是SharedPreferencesImpl,通过源码可以发现他的put和get方法都有synchronized锁,因此它是线程安全的。

SharedPreferences基本使用

存值

        SharedPreferences sp = context.getSharedPreferences("sp_storage", Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = getPreferences().edit();
        editor.putString("name", "小明");
        editor.apply();
//        editor.commit();

apply和commit的区别

editor.apply()会先存入内存,后续才同步到磁盘,比commit效率高,特别是频繁存取的时候。
editor.commit()会直接写入磁盘,并且返回boolean表示是否写入成功,适合需要根据是否成功写入磁盘这个结果做后续操作的情景使用。

取值

        SharedPreferences sp = context.getSharedPreferences("sp_storage", Context.MODE_PRIVATE);
        sp.getString("name", "");

SharedPreferences封装

//封装成Util
public class SPHelper {
    public static volatile SharedPreferences mSharedPreferences;

    public static void set(String key, int value) {
        SharedPreferences.Editor editor = getPreferences().edit();
        editor.putInt(key, value);
        editor.apply();
    }

    public static void set(String key, boolean value) {
        SharedPreferences.Editor editor = getPreferences().edit();
        editor.putBoolean(key, value);
        editor.apply();
    }

    public static void set(String key, String value) {
        SharedPreferences.Editor editor = getPreferences().edit();
        editor.putString(key, value);
        editor.apply();
    }

    public static void set(String key, long value) {
        SharedPreferences.Editor editor = getPreferences().edit();
        editor.putLong(key, value);
        editor.apply();
    }

    public static boolean get(String key, boolean defValue) {
        return getPreferences().getBoolean(key, defValue);
    }

    public static String get(String key, String defValue) {
        return getPreferences().getString(key, defValue);
    }

    public static int get(String key, int defValue) {
        return getPreferences().getInt(key, defValue);
    }

    public static long get(String key, long defValue) {
        return getPreferences().getLong(key, defValue);
    }

    public static float get(String key, float defValue) {
        return getPreferences().getFloat(key, defValue);
    }

    public static SharedPreferences getPreferences() {
        if (mSharedPreferences == null) {
            synchronized (SPHelper.class) {
                if (mSharedPreferences == null) {
                    return BaseApplication.getContext().getSharedPreferences("sp_storage", Context.MODE_PRIVATE);
                }
            }
        }
        return mSharedPreferences;
    }
}


//使用
//存
SPHelper.set("name", "小明");
//取
String name = SPHelper.get("name", "");

MMKV

MMKV是腾讯开发的比SharedPreferences更好用的库。

git地址

GitHub - Tencent/MMKV: An efficient, small mobile key-value storage framework developed by WeChat. Works on Android, iOS, macOS, Windows, and POSIX.

使用

添加依赖

dependencies {
    implementation 'com.tencent:mmkv:1.2.12'
}

在Application中初始化

//Application下
public void onCreate() {
    super.onCreate();
    MMKV.initialize(this);
}

MMKV有一个全局的实例可以直接使用,MMKV.defaultMMKV()

MMKV kv = MMKV.defaultMMKV();//全局实例
MMKV kv = MMKV.mmkvWithID("MyID");//不同的ID下的MMKV以不同的存储区域保存键值对

常规使用

import com.tencent.mmkv.MMKV;

MMKV kv = MMKV.defaultMMKV();

//键值对存取
kv.encode("isUsed", true);
boolean isUsed = kv.decodeBool("isUsed");
kv.encode("age", 15);
int age = kv.decodeInt("age");
kv.encode("name", "ZhangFei");
String name = kv.decodeString("name");
System.out.println("isUsed="+isUsed+";age="+age+";name="+name);
//输出: isUsed=true;age=15;name=ZhangFei

//单个键值对删除
kv.removeValueForKey("isUsed");
//批量删除键值对
kv.removeValuesForKeys(new String[]{"isUsed", "age"});
//判断key对应的value是不是空
boolean hasBool = kv.containsKey("isUsed");

多进程中使用

MMKV kv = MMKV.mmkvWithID("InterProcessKV", MMKV.MULTI_PROCESS_MODE);
kv.encode("name", "XiaoMing");

适配SharedPreferences以及数据迁移

private void testImportSharedPreferences() {
    MMKV preferences = MMKV.mmkvWithID("myData");
    {
        //将原来SharedPreferences的数据导入到MMKV 
        SharedPreferences old_man = getSharedPreferences("myData", MODE_PRIVATE);
        preferences.importFromSharedPreferences(old_man);
        //清空原来SharedPreferences中的数据
        old_man.edit().clear().commit();
    }

    //这种写法是减少之前使用了SharedPreferences的相关代码改动,让之前editor相关的代码可以继续使用,并且不再需要commit
    SharedPreferences.Editor editor = preferences.edit();
    editor.putBoolean("bool", true);
    editor.putInt("int", Integer.MIN_VALUE);
    editor.putLong("long", Long.MAX_VALUE);
    editor.putFloat("float", -3.14f);
    editor.putString("string", "hello, imported");
    HashSet<String> set = new HashSet<String>();
    set.add("W"); set.add("e"); set.add("C"); set.add("h"); set.add("a"); set.add("t");
    editor.putStringSet("string-set", set);
    // commit() is not needed any more
    //editor.commit();
}

原理

MMKV是通过mmap内存映射文件来进行读写操作的,因此他的效率高于普通IO。采用Protobuf协议存储key-value结构,特点是基于二进制,比SharedPreferences使用的XML表示同样一段内容要短很多。采用crc校验确保数据的有效性。多进程实现需要处理写指针增长、内存重叠、内存增长的情况。

普通IO需要将文件内容从硬盘拷贝到内核空间的一个缓冲区,再将数据拷贝到用户空间,这个过程需要两次数据拷贝。而mmap将内核空间和用户空间的部分区域映射到同一块物理空间,那么把文件内容拷贝到内核空间的这块区域,相当于也拷贝到了用户空间。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值