陕西网站建设热线/网站注册免费
目录
一、MMKV介绍
1.特点和优势:
2.使用指南:
3.依赖包:
二、MMKV的常用方法
1、初始化和获取实例:
2、存储数据:
3、读取数据
4、删除数据
5、其他操作:
三、MMKV的使用例子
MainActivity:
activity_main:
运行结果:
一、MMKV介绍
MMKV是一种用于安卓平台的轻量级键值存储库,它提供了一种高效、可靠的方式来在应用程序中存储和读取数据。
1.特点和优势:
- 高性能:相对于传统的SharedPreferences和SQLite等存储方式,MMKV在性能方面表现出色。
- 轻量级:MMKV是一个小巧的库,没有外部依赖,易于集成到现有项目中。
- 多线程支持:MMKV具备良好的多线程支持,可以在并发场景下安全地进行数据读写操作。
- 易用性:MMKV提供简单易用的API,支持各种数据类型的存储和读取操作。
- 数据安全:MMKV采用内置的AES加密机制,保护存储的数据安全。
2.使用指南:
- 引入依赖:在项目的build.gradle文件中添加MMKV的依赖项。
- 初始化MMKV:在应用程序的入口处初始化MMKV实例,可以设置存储路径、加密密钥等参数。
- 存储数据:使用putXXX()方法将数据存储到MMKV中,支持各种数据类型。
- 读取数据:使用getXXX()方法从MMKV中读取数据,并进行相应的类型转换。
- 其他操作: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在性能、存储容量、多进程并发安全性和加密等方面有着明显的优势,特别适合用于高性能要求、大数据量存储或多进程场景下的数据存储需求。
相关文章:

安卓:MMKV——键值存储库
目录 一、MMKV介绍 1.特点和优势: 2.使用指南: 3.依赖包: 二、MMKV的常用方法 1、初始化和获取实例: 2、存储数据: 3、读取数据 4、删除数据 5、其他操作: 三、MMKV的使用例子 MainActivityÿ…...

使用Python将图像转换为PDF:一次性解决您的批量转换需求
导语: 在数字化时代,我们经常需要处理大量的图像文件。将这些图像转换为PDF格式可以方便地存档、分享和打印。本文将介绍如何使用Python编程语言将图像批量转换为PDF,并提供了一个简单易用的图形界面来跟踪转换进度。 准备工作 在开始之前…...

Vue——webpack
webpack 一、Install1.全局安装2.局部安装 二、总结1.打包2.定义脚本3.配置文件定义(webpack.config.js)4.项目重新加载依赖5.webpack打包Css6.style-loader 一、Install 1.全局安装 npm install webpack webpack-cli -g2.局部安装 以项目为单位,一个项…...

springboot房地产管理java购房租房二手房j客户sp源代码mysql
本项目为前几天收费帮学妹做的一个项目,Java EE JSP项目,在工作环境中基本使用不到,但是很多学校把这个当作编程入门的项目来做,故分享出本项目供初学者参考。 一、项目描述 springboot房地产管理 系统1权限:管理员 …...

Gartner 发布影响数据科学和机器学习未来方向重要趋势
出品 | CSDN 云计算 供稿 | Gartner Gartner今日发布了影响数据科学与机器学习(DSML)未来方向的重要趋势。随着DSML行业的快速发展和演变,数据对于人工智能(AI)开发与运用的重要性日益提高,尤其是投资重点…...

72. 编辑距离
题目介绍 给你两个单词 word1 和 word2, 请返回将 word1 转换成 word2 所使用的最少操作数 。 你可以对一个单词进行如下三种操作: 插入一个字符删除一个字符替换一个字符 示例 1: 输入:word1 "horse", word2 &q…...

Android12.0 原生系统SystemUI下拉状态栏和通知栏视图之锁屏通知布局
1.前言 在12.0的系统rom定制化开发中,对于系统原生systemui的锁屏界面的功能也是非常重要的,所以在锁屏页面布局中,也是有通知栏布局的,所以接下来对于息屏亮屏 通知栏布局的相关流程分析,看下亮屏后锁屏页面做了哪些功能 2.原生系统SystemUI下拉状态栏和通知栏视图之锁…...

周末在家值班,解决几个月前遗忘的Bug
问题: 周末被迫在家值班,无聊之际打开尘封已久的Bug清单,发现有Bug拖了几个月还没解决… 场景是这样子的,有个功能是拿Redis缓存热点数据进行展示,暂且称它为功能A,有个另外的功能B,它会去更新缓…...

Shell编程基础(十五)文本三剑客(sed)
文本三剑客(sed) 使用场景基本语法实例命令列表 使用场景 sed提供了一种面交互的方式修改文件内容。 它是一行一行处理,可以通过正则匹配要修改的部分 基本语法 基本语法 sed [-opt] command files(多个文件 空格隔开) sed 使用正则 sed -…...

5,二叉树【p6-p7】
二叉树 5.1二叉树5.1.1例1:用递归和非递归两种方式实现二叉树的先序、中序、后序遍历5.1.1.1递归序的先序、中序、后序遍历先序遍历:中序遍历:后序遍历: 5.1.1.2非递归序的先序、中序、后序遍历先序遍历:中序遍历&…...

【Spring】如果你需要使用重试机制,请使用Spring官方的Spring Retry
文章目录 前言Spring Retry的基本使用第一步,引入Spring Retry的jar包第二步,构建一个RetryTemplate类第三步,使用RETRY_TEMPLATE注意事项 拓展方法降级操作重试策略:时间策略重试策略:指定异常策略 前言 Spring Retr…...

pagehelper 优化自定义分页和排序位置
pagehelper开源地址 https://github.com/pagehelper/Mybatis-PageHelper 1.手写Count查询优化 源码分页count时首先是判断是否存在手写的 {业务查询id}_COUNT 的查询count统计 private Long count(Executor executor, MappedStatement ms, Object parameter,RowBounds rowBound…...

Linux下查询文件夹中文件数量的方法
一、前言 在Linux系统中,我们经常需要查询文件夹中包含多少文件。本文将介绍三种在Linux中查询文件夹中文件数量的方法,帮助你轻松获取所需信息。 二、方法 1、使用ls命令和wc命令 使用ls命令的-l选项和管道操作符|结合wc命令来统计文件数量…...

PS透明屏,在科技展示中,有哪些优点展示?
PS透明屏是一种新型的显示技术,它将传统的显示屏幕与透明材料相结合,使得屏幕能够同时显示图像和透过屏幕看到背后的物体。 这种技术在商业展示、广告宣传、产品展示等领域有着广泛的应用前景。 PS透明屏的工作原理是利用透明材料的特性,通…...

Hbase-面试题
1. Hbase-region切分 自动切分,默认情况下 2.0版本,第一次region的数据达到256M,会进行切分,以后就是每达到10G切分一次,切分完成后,会进行负载均衡,均衡到其他regionserver预分区自定义rowke…...

图的宽度优先深度优先遍历
图常见的遍历方式有两种,一种是宽度优先遍历,一种是深度优先遍历。 宽度优先遍历 宽度优先遍历和之前介绍的二叉树的层级遍历类似,主要也是利用Queue来完成层级的遍历,除此之外,因为图中很可能有环,所以还…...

redis Set类型命令
Redis中的Set是一种无序、不重复的集合数据结构,它提供了一系列的操作命令用于对Set进行添加、删除和查找等操作。以下是Redis中Set类型常见的一些命令: SADD key member [member …]:将一个或多个成员添加到指定的集合中。 示例:…...

Netty框架自带类DefaultEventExecutorGroup的作用,用来做业务的并发
一、DefaultEventExecutorGroup的用途 DefaultEventExecutorGroup 是 Netty 框架中的一个类,用于管理和调度事件处理器(EventExecutor)的组。在 Netty 中,事件处理是通过多线程来完成的,EventExecutor 是处理事件的基…...

TCP的四次挥手与TCP状态转换
文章目录 四次挥手场景步骤TCP状态转换 四次挥手场景 TCP客户端与服务器断开连接的时候,在程序中使用close()函数,会使用TCP协议四次挥手。 客户端和服务端都可以主动发起。 因TCP连接时候是双向的,所以断开的时候也是双向的。 步骤 三次…...

【网络编程】实现一个简单多线程版本TCP服务器(附源码)
TCP多线程 🌵预备知识🎄 Accept函数🌲字节序转换函数🌳listen函数 🌴代码🌱Log.hpp🌿Makefile☘️TCPClient.cc🍀TCPServer.cc🎍 util.hpp 🌵预备知识 &…...

centos离线部署docker
有些内部环境需要离线部署,以下做一些备忘。 环境:centos7.9 准备文件: docker-20.10.9.tgz,下载地址 https://download.docker.com/linux/static/stable/x86_64/docker.service,内容见下文daemon.json,内…...

ffmpeg使用滤镜对视频进行处理播放
一、前言 在现代的多媒体处理中,视频和音频滤镜起着至关重要的作用。可以帮助开发者对视频和音频进行各种处理,如色彩校正、尺寸调整、去噪、特效添加等。而FFmpeg作为一个功能强大的开源多媒体框架,提供了丰富的滤镜库,使我们能够轻松地对多媒体文件进行处理和转换。 本…...

Ansible Handlers模块详解,深入理解Ansible Handlers 自动化中的关键组件
深入理解Ansible Handlers 自动化中的关键组件 在现代的IT环境中,自动化已经成为提高效率和减少错误的关键。Ansible作为一款流行的自动化工具,通过使用Playbooks来定义和执行任务。而Handlers作为Ansible的组件之一,在自动化过程中发挥着重要…...

threejs点击模型实现模型边缘高亮的选中效果--更改后提高帧率
先来个效果图 之前写的那个稍微有点问题,帧率只有30,参照官方代码修改后,帧率可以达到50了,在不全屏的状态下,帧率60 1.首先需要导入库 // 用于模型边缘高亮 import { EffectComposer } from "three/examples/js…...

RocketMQ 主备自动切换模式部署
目录 主备自动切换模式部署 Controller 部署 Controller 嵌入 NameServer 部署 Controller 独立部署 Broker 部署 兼容性 升级注意事项 主备自动切换模式部署 该文档主要介绍如何部署支持自动主从切换的 RocketMQ 集群,其架构如上图所示ÿ…...

【MySQL】select相关
文章目录 迭代器distinct 关键字limit offset 关键字order by 列名 asc\descselect语句的执行顺序几点注意 迭代器 指向第一个元素 使用hasNext()进行判断后才进行取元素 resultSet:指向第一个元素前一个 distinct 关键字 去除一列中的重复元素 可以进行多行的去重…...

在Python中应用RSA算法实现图像加密:基于Jupyter环境的详细步骤和示例代码
一、引言 在当今的数字化社会中,信息安全问题备受关注。随着数字图像在生活中的应用越来越广泛,图像的安全性和隐私性也成为人们关心的焦点。如何在网络上安全地传输和存储图像已经成为一项重要的挑战。RSA(Rivest-Shamir-Adleman)算法作为一种被广泛应用的公钥密码体系,…...

Prometheus Blackbox Exporter 的 HTTP 探测指标中各个阶段的时间统计信息
在 Prometheus Blackbox Exporter 的 HTTP 探测指标中,probe_http_duration_seconds 指标包含各个阶段的时间统计信息。这些阶段代表了 HTTP 探测的不同阶段和指标。以下是各个阶段的含义: phase"dns_lookup":这是指进行 DNS 查找…...

数据结构之时间复杂度-空间复杂度
大家好,我是深鱼~ 目录 1.数据结构前言 1.1什么是数据结构 1.2什么是算法 1.3数据结构和算法的重要性 1.4如何学好数据结构和算法 2.算法的效率 3.时间复杂度 3.1时间复杂度的概念 3.2大O的渐进表示法 【实例1】:双重循环的时间复杂度…...

新一代构建工具 maven-mvnd
新一代构建工具 maven-mvnd mvnd的前世今生下载安装 mvndIDEA集成 mvnd的前世今生 maven 作为一代经典的构建工具,流行了很多年,知道现在依然是大部分Java项目的构建工具的首选;但随着项目复杂度提高,代码量及依赖库的增多使得ma…...