MMKV替换SharedPreferences详解

一.简介

官网解释:微信开发的高效小型移动键值存储框架。适用于Android, iOS, macOS, Windows和POSIX。

可以多进程通信,实际上就是共享文件的形式。MMKV基于mmap内存映射的Key-Value。底层序列化和反序列化使用protobuf。性能高,稳定性强。可以实现从SharedPreference无缝转换,极其方便。
 

 

 

 

 

 

 

二.MMKV基本使用

 

1.Gradle依赖

implementation 'com.tencent:mmkv:1.0.23'

 

 

2.代码

public class MMKVActivity extends AppCompatActivity {

    private MMKV mmkv;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_mmkv);
        //初始化 一般可以放到Application中
        MMKV.initialize(this);
        //获取MMKV对象
        mmkv = MMKV.defaultMMKV();

        //存数据
        findViewById(R.id.textview1).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //存Int类型
                mmkv.encode("IntKey", 1234);
                //存Long类型
                mmkv.encode("LongKey", 123456l);
                //存Float类型
                mmkv.encode("FloatKey", 12.34f);
                //存Double类型
                mmkv.encode("DoubleKey", 123.456d);
                //存String类型
                mmkv.encode("StringKey", "李四");
                //存布尔类型
                mmkv.encode("BooleanKey", true);
                //存Byte[]类型
                byte[] bytes = new byte[]{1, 2, 3};
                mmkv.encode("ByteKey", bytes);
                //存StringSet类型
                Set<String> set = new HashSet<>();
                set.add("StringSet111");
                set.add("StringSet222");
                set.add("StringSet333");
                mmkv.encode("StringSetKey", set);
                //存实现了Parcelable的实体类
                Book book = new Book();
                book.setBookId(123456);
                book.setBookLabel("Parcelable接口实现序列化-图书标签");
                book.setBookName("Parcelable接口实现序列化-图书名称");
                book.setBookPrice(56.78f);
                mmkv.encode("ParcelableKey", book);
                //最终提交
                mmkv.apply();
            }
        });

        //取数据
        findViewById(R.id.textview2).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int i = mmkv.decodeInt("IntKey", -1);
                long l = mmkv.decodeLong("LongKey", -1);
                float f = mmkv.decodeFloat("FloatKey", -1);
                double d = mmkv.decodeDouble("DoubleKey", -1);
                String s = mmkv.decodeString("StringKey", "");
                boolean b = mmkv.decodeBool("BooleanKey", false);
                byte[] bytes = mmkv.decodeBytes("ByteKey", new byte[]{7});
                Set<String> set = mmkv.decodeStringSet("StringSetKey");
                Book book = mmkv.decodeParcelable("ParcelableKey", Book.class);
                Log.d("MMKVActivity", "MMKV取值 Int类型 ----:" + i);
                Log.d("MMKVActivity", "MMKV取值 Long类型 ----:" + l);
                Log.d("MMKVActivity", "MMKV取值 Float类型 ----:" + f);
                Log.d("MMKVActivity", "MMKV取值 Double类型 ----:" + d);
                Log.d("MMKVActivity", "MMKV取值 Boolean类型 ----:" + b);
                Log.d("MMKVActivity", "MMKV取值 String类型 ----:" + s);
                Log.d("MMKVActivity", "MMKV取值 Byte类型 bytes----:" + bytes.toString());
                Log.d("MMKVActivity", "MMKV取值 Set类型 set----:" + set);

                if (null != book) {
                    Log.d("MMKVActivity", "MMKV取值 Set类型 book.toString()----:" + book.toString());
                }

                for (byte by : bytes) {
                    Log.d("MMKVActivity", "MMKV取值 Byte类型 by----:" + by);
                }

                if (null != set) {
                    for (String string : set) {
                        Log.d("MMKVActivity", "MMKV取值 Set类型 string ----:" + string);
                    }
                }
            }
        });

        //清空数据
        findViewById(R.id.textview3).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mmkv.clearAll();
                //最终提交
                mmkv.apply();
            }
        });
    }
}

 

实现Parcelable的实体类

/**
 * 图书实体类 Parcelable接口实现序列化
 */

public class Book implements Parcelable {

    private int bookId;
    private String bookName;
    private String bookLabel;
    private float bookPrice;

    public Book() {

    }

    /**
     * 构造方法 可按报错提示自动生成
     */

    protected Book(Parcel in) {
        bookId = in.readInt();
        bookName = in.readString();
        bookLabel = in.readString();
        bookPrice = in.readFloat();
    }

    /**
     * Creator对象 可按报错提示自动生成
     */

    public static final Creator<Book> CREATOR = new Creator<Book>() {
        @Override
        public Book createFromParcel(Parcel in) {
            return new Book(in);
        }

        @Override
        public Book[] newArray(int size) {
            return new Book[size];
        }
    };

    public int getBookId() {
        return bookId;
    }

    public void setBookId(int bookId) {
        this.bookId = bookId;
    }

    public String getBookName() {
        return bookName;
    }

    public void setBookName(String bookName) {
        this.bookName = bookName;
    }

    public String getBookLabel() {
        return bookLabel;
    }

    public void setBookLabel(String bookLabel) {
        this.bookLabel = bookLabel;
    }

    public float getBookPrice() {
        return bookPrice;
    }

    public void setBookPrice(float bookPrice) {
        this.bookPrice = bookPrice;
    }

    /**
     * 实现Parcelable接口 重写的方法
     */

    @Override
    public int describeContents() {
        return 0;
    }

    /**
     * 实现Parcelable接口 重写的方法
     */

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(bookId);
        dest.writeString(bookName);
        dest.writeString(bookLabel);
        dest.writeFloat(bookPrice);
    }

    @Override
    public String toString() {
        return "Book{" +
                "bookId=" + bookId +
                ", bookName='" + bookName + '\'' +
                ", bookLabel='" + bookLabel + '\'' +
                ", bookPrice=" + bookPrice +
                '}';
    }
}

 

 

3.结果

存值 然后 取值

D/MMKVActivity: MMKV取值 Int类型 ----:1234


D/MMKVActivity: MMKV取值 Long类型 ----:123456


D/MMKVActivity: MMKV取值 Float类型 ----:12.34


D/MMKVActivity: MMKV取值 Double类型 ----:123.456


D/MMKVActivity: MMKV取值 Boolean类型 ----:true


D/MMKVActivity: MMKV取值 String类型 ----:李四


D/MMKVActivity: MMKV取值 Byte类型 bytes----:[B@236cfe3


D/MMKVActivity: MMKV取值 Set类型 set----:[StringSet222, StringSet111, StringSet333]


D/MMKVActivity: MMKV取值 Set类型 book.toString()----:Book{bookId=123456, bookName='Parcelable接口实现序列化-图书名称', bookLabel='Parcelable接口实现序列化-图书标签', bookPrice=56.78}


D/MMKVActivity: MMKV取值 Byte类型 by----:1


D/MMKVActivity: MMKV取值 Byte类型 by----:2


D/MMKVActivity: MMKV取值 Byte类型 by----:3


D/MMKVActivity: MMKV取值 Set类型 string ----:StringSet222


D/MMKVActivity: MMKV取值 Set类型 string ----:StringSet111


D/MMKVActivity: MMKV取值 Set类型 string ----:StringSet333

 

清空然后 取值

D/MMKVActivity: MMKV取值 Int类型 ----:-1


D/MMKVActivity: MMKV取值 Long类型 ----:-1


D/MMKVActivity: MMKV取值 Float类型 ----:-1.0


D/MMKVActivity: MMKV取值 Double类型 ----:-1.0


D/MMKVActivity: MMKV取值 Boolean类型 ----:false


D/MMKVActivity: MMKV取值 String类型 ----:


D/MMKVActivity: MMKV取值 Byte类型 bytes----:[B@236cfe3


D/MMKVActivity: MMKV取值 Set类型 set----:null


D/MMKVActivity: MMKV取值 Byte类型 by----:7

 

 

4.说明

上述 存储Long类型 Float类型 Double类型 时 最好有后缀 。比如123456l   12.34f  123.456d。 

 

 

 

 

 

 

 

三.方法说明

 

1.初始化MMKV

MMKV.initialize(this);

一般在Application中初始化。其他Activity/Fragment直接使用即可。

初始化方法,有多个重载方法。常用的几个举例。

 

<1> 传参:上下文对象

public static String initialize(Context context) {
    String root = context.getFilesDir().getAbsolutePath() + "/mmkv";
    MMKVLogLevel logLevel = MMKVLogLevel.LevelInfo;
    return initialize(root, (MMKV.LibLoader)null, logLevel);
}
String path = MMKV.initialize(this);

得到的路径

/data/user/0/com.wjn.rxdemo/files/mmkv

 

 

<2> 传参:自定义路径

public static String initialize(String rootDir) {
    MMKVLogLevel logLevel = MMKVLogLevel.LevelInfo;
    return initialize(rootDir, (MMKV.LibLoader)null, logLevel);
}
String path = MMKV.initialize("/data/user/0/com.wjn.rxdemo/files/mmkv/mymmkv");

得到的路径

自定义的路径。

 

 

 

2.获取MMKV对象

//默认
MMKV mmkv = MMKV.defaultMMKV();



//加密 
MMKV mmkv = MMKV.defaultMMKV(Context.MODE_APPEND,"cryptKey");

 

 

3.存各种类型的值

//存Int类型
mmkv.encode("IntKey", 1234);

//存Long类型
mmkv.encode("LongKey", 123456l);

//存Float类型
mmkv.encode("FloatKey", 12.34f);

//存Double类型
mmkv.encode("DoubleKey", 123.456d);

//存String类型
mmkv.encode("StringKey", "李四");

//存布尔类型
mmkv.encode("BooleanKey", true);

//存Byte[]类型
byte[] bytes = new byte[]{1, 2, 3};
mmkv.encode("ByteKey", bytes);

//存StringSet类型
Set<String> set = new HashSet<>();
set.add("StringSet111");
set.add("StringSet222");
set.add("StringSet333");
mmkv.encode("StringSetKey", set);

 

 

4.提交存值

mmkv.apply();

mmkv.commit();

和SharedPreferences一样。MMKV也有两个提交方法。apply()方法和commit()方法。

public void apply() {
    this.sync(false);
}
public boolean commit() {
    this.sync(true);
    return true;
}

 

 

5.清除数据

<1> 清空全部数据

mmkv.clearAll();

 

<2> 清除指定Key对应的数据

mmkv.remove("StringKey");

 

 

 

 

 

 

 

四.迁移SharedPreference数据

MMKV迁移SharedPreference数据特别简单。因为MMKV有一个类 MMKV类 实现了SharedPreference接口和Editor接口。并且提供了专门迁移的方法 importFromSharedPreferences()方法

public class MMKV implements SharedPreferences, Editor {


 public int importFromSharedPreferences(SharedPreferences preferences) {
        Map<String, ?> kvs = preferences.getAll();
        if (kvs != null && kvs.size() > 0) {
            Iterator var3 = kvs.entrySet().iterator();

            while(var3.hasNext()) {
                Entry<String, ?> entry = (Entry)var3.next();
                String key = (String)entry.getKey();
                Object value = entry.getValue();
                if (key != null && value != null) {
                    if (value instanceof Boolean) {
                        this.encodeBool(this.nativeHandle, key, (Boolean)value);
                    } else if (value instanceof Integer) {
                        this.encodeInt(this.nativeHandle, key, (Integer)value);
                    } else if (value instanceof Long) {
                        this.encodeLong(this.nativeHandle, key, (Long)value);
                    } else if (value instanceof Float) {
                        this.encodeFloat(this.nativeHandle, key, (Float)value);
                    } else if (value instanceof Double) {
                        this.encodeDouble(this.nativeHandle, key, (Double)value);
                    } else if (value instanceof String) {
                        this.encodeString(this.nativeHandle, key, (String)value);
                    } else if (value instanceof Set) {
                        this.encode(key, (Set)value);
                    } else {
                        simpleLog(MMKVLogLevel.LevelError, "unknown type: " + value.getClass());
                    }
                }
            }

            return kvs.size();
        } else {
            return 0;
        }
    }



}

 

 

原SharedPreferences数据源

<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<map>
    <float name="floatType" value="12.34" />
    <boolean name="booleanType" value="false" />
    <string name="stringType">张三</string>
    <int name="intType" value="12" />
    <set name="setType">
        <string>Set222</string>
        <string>Set333</string>
        <string>Set111</string>
    </set>
    <long name="longType" value="123456" />
</map>

 

 

取值Key

//存Int类型
editor.putInt("intType", 12);

//存Long类型
editor.putLong("longType", 123456);

//存Float类型
editor.putFloat("floatType", 12.34f);

//存Boolean类型
editor.putBoolean("booleanType", false);

//存String类型
editor.putString("stringType", "张三");

//存StringSet类型
Set<String> strings = new HashSet<>();
strings.add("Set111");
strings.add("Set222");
strings.add("Set333");
editor.putStringSet("setType", strings);

 

 

迁移代码

package com.wjn.rxdemo.datastore;

import android.content.Context;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.util.Log;
import android.view.View;

import androidx.appcompat.app.AppCompatActivity;

import com.tencent.mmkv.MMKV;
import com.wjn.rxdemo.R;

import java.util.Set;

import static com.wjn.rxdemo.datastore.SharedPreferenceActivity.SHARED_PREFERENCES_NAME;

public class MMKVActivity extends AppCompatActivity {

    private MMKV mmkv;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_mmkv);
        //初始化 一般可以放到Application中
        MMKV.initialize(this);
        //获取MMKV对象
        mmkv = MMKV.mmkvWithID(SHARED_PREFERENCES_NAME);

        //迁移SharedPreferences数据
        findViewById(R.id.textview1).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //获取SHARED_PREFERENCES_NAME 对应的SharedPreference对象
                SharedPreferences sharedPreferences = getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
                //MMKV的importFromSharedPreferences迁移 上面获取的SharedPreference对象
                mmkv.importFromSharedPreferences(sharedPreferences);
                //原SharedPreference对象内容删除
                sharedPreferences.edit().clear().apply();
            }
        });

        //取数据
        findViewById(R.id.textview2).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int i = mmkv.decodeInt("intType", -1);
                long l = mmkv.decodeLong("longType", -1);
                float f = mmkv.decodeFloat("floatType", -1);
                boolean b = mmkv.decodeBool("booleanType", false);
                String s = mmkv.decodeString("stringType", "");
                Set<String> set = mmkv.decodeStringSet("setType", null);
                Log.d("MMKVActivity", "MMKV取值 Int类型 ----:" + i);
                Log.d("MMKVActivity", "MMKV取值 Long类型 ----:" + l);
                Log.d("MMKVActivity", "MMKV取值 Float类型 ----:" + f);
                Log.d("MMKVActivity", "MMKV取值 Boolean类型 ----:" + b);
                Log.d("MMKVActivity", "MMKV取值 String类型 ----:" + s);
                if (null != set) {
                    for (String string : set) {
                        Log.d("MMKVActivity", "MMKV取值 Set类型 string ----:" + string);
                    }
                }
            }
        });
    }
}

 

 

结果

D/MMKVActivity: MMKV取值 Int类型 ----:12

D/MMKVActivity: MMKV取值 Long类型 ----:123456

D/MMKVActivity: MMKV取值 Float类型 ----:12.34

D/MMKVActivity: MMKV取值 Boolean类型 ----:false

D/MMKVActivity: MMKV取值 String类型 ----:张三

D/MMKVActivity: MMKV取值 Set类型 string ----:Set222

D/MMKVActivity: MMKV取值 Set类型 string ----:Set333

D/MMKVActivity: MMKV取值 Set类型 string ----:Set111

 

 

因为迁移时清空了原来的SharedPreference。原xml内容如下

<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<map />

 

 

 

 

附:MMKV GitHub官方地址:https://github.com/Tencent/MMKV

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值