安卓:MMKV——键值存储库

目录

一、MMKV介绍

1.特点和优势:

 2.使用指南:

 3.依赖包:

二、MMKV的常用方法

1、初始化和获取实例:

2、存储数据:

 3、读取数据

4、删除数据

 5、其他操作:

三、MMKV的使用例子

 MainActivity:

 activity_main:

运行结果:

四、MMKV与SharedPreferences比较

一、MMKV介绍

        MMKV是一种用于安卓平台的轻量级键值存储库,它提供了一种高效、可靠的方式来在应用程序中存储和读取数据。

1.特点和优势:

  • 高性能:相对于传统的SharedPreferences和SQLite等存储方式,MMKV在性能方面表现出色。
  • 轻量级:MMKV是一个小巧的库,没有外部依赖,易于集成到现有项目中。
  • 多线程支持:MMKV具备良好的多线程支持,可以在并发场景下安全地进行数据读写操作。
  • 易用性:MMKV提供简单易用的API,支持各种数据类型的存储和读取操作。
  • 数据安全:MMKV采用内置的AES加密机制,保护存储的数据安全。

 2.使用指南:

  1. 引入依赖:在项目的build.gradle文件中添加MMKV的依赖项。
  2. 初始化MMKV:在应用程序的入口处初始化MMKV实例,可以设置存储路径、加密密钥等参数。
  3. 存储数据:使用putXXX()方法将数据存储到MMKV中,支持各种数据类型。
  4. 读取数据:使用getXXX()方法从MMKV中读取数据,并进行相应的类型转换。
  5. 其他操作:MMKV还提供了删除特定键值、清空所有数据等操作。

 3.依赖包:

​dependencies {implementation 'com.tencent:mmkv:1.2.10'}

二、MMKV的常用方法

1、初始化和获取实例:

String rootDir = MMKV.initialize(context); // 初始化默认根目录
MMKV mmkv = MMKV.defaultMMKV(); // 获取默认的MMKV实例

2、存储数据:

mmkv.encode("key", value); // 存储数据,自动根据类型选择合适的方法
// 或者使用特定类型的存储方法
mmkv.putInt("intKey", intValue);
mmkv.putLong("longKey", longValue);
mmkv.putFloat("floatKey", floatValue);
mmkv.putBoolean("booleanKey", booleanValue);
mmkv.putString("stringKey", stringValue);
mmkv.putStringSet("setKey", stringSet);

 3、读取数据

Object value = mmkv.decode("key"); // 读取数据,自动根据类型选择合适的方法
// 或者使用特定类型的读取方法
int intValue = mmkv.getInt("intKey", defaultValue);
long longValue = mmkv.getLong("longKey", defaultValue);
float floatValue = mmkv.getFloat("floatKey", defaultValue);
boolean booleanValue = mmkv.getBoolean("booleanKey", defaultValue);
String stringValue = mmkv.getString("stringKey", defaultValue);
Set<String> stringSet = mmkv.getStringSet("setKey", defaultSet);

4、删除数据

mmkv.remove("key"); // 删除指定键值对
mmkv.removeValueForKey("key"); // 同上,作用相同
mmkv.removeValuesForKeys(new String[]{"key1", "key2"}); // 删除多个键值对
mmkv.clearAll(); // 清空所有数据

 5、其他操作:

boolean contains = mmkv.containsKey("key"); // 判断是否包含指定的键
int count = mmkv.count(); // 获取存储的数据总数
String[] allKeys = mmkv.allKeys(); // 获取所有存储的键

三、MMKV的使用例子

 MainActivity:

package com.example.mmkvdemo;import androidx.appcompat.app.AppCompatActivity;import android.app.Activity;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.Toast;import com.tencent.mmkv.MMKV;public class MainActivity extends AppCompatActivity implements CompoundButton.OnCheckedChangeListener {EditText password, account;Button login, register;CheckBox mCheckBox;String Password, Account;MMKV mmkv;String TAG = "MainActivity";@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initView();// 初始化MMKVString rootDir = MMKV.initialize(this);Log.d(TAG, "路径:" + rootDir);// 读取保存的账号和密码mmkv = MMKV.defaultMMKV();if (mmkv.contains("account") && mmkv.contains("password")) {Account = mmkv.decodeString("account", "");Password = mmkv.decodeString("password", "");account.setText(Account);password.setText(Password);}}private void initView() {mCheckBox = findViewById(R.id.Login_Remember);login = findViewById(R.id.login_btn_login);register = findViewById(R.id.login_btn_register);password = findViewById(R.id.login_edit_pwd);account = findViewById(R.id.login_edit_account);mCheckBox.setOnCheckedChangeListener(this);register.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {Toast.makeText(MainActivity.this, "点击了注册", Toast.LENGTH_LONG).show();}});login.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {Toast.makeText(MainActivity.this, "点击了登录", Toast.LENGTH_LONG).show();}});}@Overridepublic void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {if (isChecked) {if (!TextUtils.isEmpty(password.getText().toString()) && !TextUtils.isEmpty(account.getText().toString())) {// 存储数据Account = account.getText().toString();Password = password.getText().toString();mmkv.putString("account", Account); // 存储数据mmkv.putString("password", Password);}} else {// 清除保存的账号和密码mmkv.removeValuesForKeys(new String[]{"account", "password"});}}
}

 activity_main:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:orientation="vertical"android:layout_width="match_parent"android:layout_height="match_parent"><RelativeLayoutandroid:id="@+id/login_view"android:layout_width="400dp"android:layout_height="800dp"android:layout_centerInParent="true"><Buttonandroid:id="@+id/login_btn_register"android:layout_width="fill_parent"android:layout_height="wrap_content"android:layout_below="@+id/login_btn_login"android:layout_alignParentStart="true"android:layout_alignParentLeft="true"android:layout_marginTop="10dp"android:background="#e52525"android:text="注册"android:textColor="#ffffff"android:textSize="20dp" /><Buttonandroid:id="@+id/login_btn_login"android:layout_width="fill_parent"android:layout_height="wrap_content"android:layout_below="@+id/login_edit_pwd"android:layout_alignParentStart="true"android:layout_alignParentLeft="true"android:layout_marginTop="52dp"android:background="#545bcb"android:text="登录"android:textColor="#ffffff"android:textSize="20dp" /><EditTextandroid:id="@+id/login_edit_pwd"android:layout_width="400dp"android:layout_height="60dp"android:layout_below="@+id/login_edit_account"android:layout_alignParentStart="true"android:layout_alignParentLeft="true"android:ems="10"android:hint="请输入您的密码"android:inputType="textPassword"android:textColor="#ffff00" /><EditTextandroid:id="@+id/login_edit_account"android:layout_width="400dp"android:layout_height="60dp"android:layout_alignParentStart="true"android:layout_alignParentLeft="true"android:layout_marginTop="20dp"android:hint="请输入您的用户名"android:inputType="textPersonName"android:textColor="#ffff00" /><CheckBoxandroid:id="@+id/Login_Remember"android:layout_width="100dp"android:layout_height="20dp"android:layout_below="@+id/login_edit_pwd"android:layout_alignParentStart="true"android:layout_alignParentLeft="true"android:checked="false"android:text="记住密码"android:textSize="15dp" /><TextViewandroid:id="@+id/login_text_change_pwd"android:layout_width="65dp"android:layout_height="20dp"android:layout_below="@+id/login_edit_pwd"android:layout_alignParentEnd="true"android:layout_alignParentRight="true"android:text="忘记密码"android:textSize="15dp" /></RelativeLayout>
</LinearLayout>

运行结果:

 

四、MMKV与SharedPreferences比较

MMKV相对于SharedPreferences(sp)有以下几个优势:

1. 性能更好:MMKV使用了自定义的键值存储引擎,底层采用了mmap映射文件的方式,避免了内存拷贝和序列化/反序列化的开销。相比之下,SharedPreferences是基于XML文件的存储,每次读写都需要进行IO操作,性能较低。

2. 存储容量更大:MMKV支持将数据存储在独立的文件中,并且可以设置单个文件的最大大小,而SharedPreferences则是将数据存储在一个XML文件中,当存储的数据量较大时,性能会下降。

3. 多进程并发安全:MMKV通过文件锁机制来实现多进程并发安全访问,避免了数据错乱和冲突的问题。而SharedPreferences没有提供多进程并发安全的保证,当多个进程同时对同一个SharedPreferences文件进行操作时,可能会导致数据异常。

4. 支持自定义加密:MMKV支持自定义的加密器,可以对存储的数据进行加密保护,增加数据的安全性。而SharedPreferences不直接支持加密,需要开发者手动对存储的数据进行加密处理。

5. API更简洁易用:MMKV提供了简洁易用的API,使用起来更加方便快捷,可以直接存储各种类型的数据,无需手动进行类型转换。而SharedPreferences需要手动进行类型转换和键值的拼接。

        总的来说,MMKV相对于SharedPreferences在性能、存储容量、多进程并发安全性和加密等方面有着明显的优势,特别适合用于高性能要求、大数据量存储或多进程场景下的数据存储需求。

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/82516.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

自然语言处理学习笔记(六)————字典树

目录 1.字典树 &#xff08;1&#xff09;为什么引入字典树 &#xff08;2&#xff09;字典树定义 &#xff08;3&#xff09;字典树的节点实现 &#xff08;4&#xff09;字典树的增删改查 DFA&#xff08;确定有穷自动机&#xff09; &#xff08;5&#xff09;优化 1.…

pytest自动化测试框架之标记用例(指定执行、跳过用例、预期失败)

pytest中提供的mark模块&#xff0c;可以实现很多功能&#xff0c;如&#xff1a; 标记用例&#xff0c;即打标签skip、skipif标记跳过&#xff0c;skip跳过当前用例&#xff0c;skipif符合情况则跳过当前用例xfail标记为预期失败 标记用例 有时候我们可能并不需要执行项目中…

ffmpeg.c源码与函数关系分析

介绍 FFmpeg 是一个可以处理音视频的软件&#xff0c;功能非常强大&#xff0c;主要包括&#xff0c;编解码转换&#xff0c;封装格式转换&#xff0c;滤镜特效。FFmpeg支持各种网络协议&#xff0c;支持 RTMP &#xff0c;RTSP&#xff0c;HLS 等高层协议的推拉流&#xff0c…

leetcode26-删除有序数组中的重复项

双指针—快慢指针 慢指针 slow 走在后面&#xff0c;快指针 fast 走在前面探路&#xff0c;找到一个不重复的元素的时候就让slow前进一步并赋值给它。 流程&#xff1a; 代码 class Solution { public:int removeDuplicates(vector<int>& nums) {int slow 0, fas…

HarmonyOS系统级推送服务,打造消息通知新体验

8月4日&#xff0c;第五届华为开发者大会 2023(HDC.Together)再次启航。在本次大会上&#xff0c;华为为广大用户带来了HarmonyOS 4.0全新升级的体验&#xff0c;同时&#xff0c;针对HarmonyOS应用的开发&#xff0c;此次也全面升级了HarmonyOS SDK开放能力。账号服务、支付、…

加量不加价,比亚迪驱逐舰05焕发新生,冠军加新120km豪华版来袭

根据最新消息&#xff0c;比亚迪驱逐舰05冠军版推出了一款崭新的豪华车型&#xff0c;其预售价为11.98万元。该车具备出色的续航性能&#xff0c;最高续航里程可达1200公里&#xff0c;并且支持17千瓦直流快速充电、VTOL移动电站以及NFC全场景数字钥匙。 此外&#xff0c;该车…

质检工具(FindBugs、CheckStyle、Junit、Jmeter、Apifox)

1、Findbugs IDEA软件中可以装该插件,2018版本以前主要搜索FindBugs-IDEA 、2018版本以后主要搜索 SpotBugs。 1.1、FindBugs-IDEA安装及使用流程: 1.2、SpotBugs安装及使用流程: 2、Checkstyle IDEA软件中可以装该插件,所有版本的插件一致:CheckStyle 2.1、安装流程…

命令模式 Command Pattern 《游戏设计模式》学习笔记

对于一般的按键输入&#xff0c;我们通常这么做&#xff0c;直接if按了什么键&#xff0c;就执行相应的操作 在这里我们是将用户的输入和程序行为硬编码在一起&#xff0c;这是我们很自然就想到的最快的做法。 但是如果这是一个大型游戏&#xff0c;往往我们需要实现一个按键…

springboot访问请求404的原因

是记录&#xff0c;可能出现错误 可能出现的原因 1.你请求的URL路径不对,比如说你请求的路径是/usr/list,GET方法,但是你UserController上面的RequestMapping是这个样子:RequestMapping(“user”)&#xff0c;有可能哈 2.前端的请求时GET方法&#xff0c;后端对应的处理函数的方…

分布式任务调度平台XXL-JOB学习笔记-helloworld运行

环境&#xff1a;win10 eclipse java17 mysql8.0.17 xxl-job 2.4 源码&#xff1a;https://github.com/xuxueli/xxl-job/ 导入时按Existing Maven Projects导入&#xff0c;先导入xxl-job-admin&#xff08;管理平台&#xff09;和xxl-job-executor-sample-springboot&#x…

【前端|Javascript第3篇】探秘JavaScript的作用域与作用域链:小白也能轻松搞懂!

大家好&#xff01;欢迎来到本篇博客&#xff0c;今天我们将解开JavaScript编程世界中的一道神秘面纱&#xff1a;作用域与作用域链。很多Javascript开发者并不真正理解它们&#xff0c;但这些概念对掌握Javascript至关重要。如果你对这些概念感到困惑&#xff0c;不要担心&…

卡尔曼滤波算法demo

代码 learn_kalman.py #codingutf-8 import numpy as np import time from kinematic_model import freedrop from controller import kalman_filterimport matplotlib.pyplot as plt # 支持中文 import matplotlib as mpl mpl.rcParams[font.family]SimHei plt.rcParams[a…

rust-异步学习

rust获取future中的结果 两种主要的方法使用 async: async fn 和 async 块 async 体以及其他 future 类型是惰性的&#xff1a;除非它们运行起来&#xff0c;否则它们什么都不做。 运行 Future 最常见的方法是 .await 它。 当 .await 在 Future 上调用时&#xff0c;它会尝试把…

idea双击启动无效,idea卡顿问题

idea双击启动无效&#xff1a;大概率是关机时没有正确关闭idea&#xff0c;再次开机导致无法正常启动idea 1.通过任务管理器杀死idea进程后重启idea 2.需要修改配置 打开 &#xff08;以各自电脑实际为准&#xff09;C:\Program Files\JetBrains\IntelliJ IDEA 2020.3.1\bin&am…

【报错】ModuleNotFoundError: No module named ‘websocket‘

1 报错 ModuleNotFoundError: No module named websocket 2 解决方法 pip install websocket 1 报错 AttributeError: module websocket has no attribute enableTrace 2 分析 一般是由于websocket的依赖包没有安装造成的。websocket.enableTrace()方法是在websocket-cli…

ffmpeg工具实用命令

说明&#xff1a;ffmpeg是一款非常好用的媒体操作工具&#xff0c;包含了许多对于视频、音频的操作&#xff0c;有些视频播放器&#xff0c;实际上就是套了一个ffmpeg的壳子。本文介绍ffmpeg的使用以及一些较为实用的命令。 安装 ffmpeg是命令行操作的&#xff0c;不需要安装…

自编码器的学习

先奉上视频 https://www.bilibili.com/video/BV1Vx411j78H/?spm_id_from333.788.recommend_more_video.-1&vd_sourceeb433c8780bdd700f49c6fc8e3bd0911

C++项目:在线五子棋对战网页版--session管理模块开发

session 在WEB开发中&#xff0c;HTTP协议是⼀种⽆状态短链接的协议&#xff0c;这就导致⼀个客⼾端连接到服务器上之后&#xff0c;服务器不知道当前的连接对应的是哪个用户&#xff0c;也不知道客⼾端是否登录成功&#xff0c;这时候为客⼾端提所有服务是不合理的。因此&am…

乐鑫首创|使用 ESP RainMaker® 私有云定制 Matter 生态

ESP RainMaker 是乐鑫的 AIoT 云平台&#xff0c;支持客户自主部署私有物联网云&#xff0c;从而全面掌握数据所有权和管理权&#xff0c;实现定制功能与服务。ESP RainMaker 云后端采用 AWS 无服务器架构&#xff0c;拥有开源的 iOS 和 Android 移动端 APP、第三方语音助手集成…

手搓 自然语言模型 LLM 拆分em结构设计 网络参数对比

数据 数据集 新的em编码参数表 voc_sizehidden_sizetotaltotal Bmax_lensecondsdays65536512374865920.03749B10242560.2655361024828375040.08284B20485120.5655362048<