Android Studio:键值对存储sharedPreferences

news2025/2/18 18:28:22

一、了解 SharedPreferences

        SharedPreferences是Android的一个轻量级存储工具,它采用的存储结构是Key-Value的键值对方式,类似于Java的Properties,二者都是把Key-Value的键值对保存在配置文件中。不同的是,Properties的文件内容形如Key=Value,而SharedPreferences的存储介质是XML文件,且以XML标记保存键值对。保存共享参数键值对信息的文件路径为:/data/data/应用包名/shared prefs/文件名.xml。下面是一个共享参数的XML文件例子:

<?xml version="1.0" encoding="utf-8"?>
<map>
    <string name="dark_mode">true</string>
    <string name="language">en</string>
    <boolean name="is_logged_in">true</boolean>
    <string name="user_id">12345</string>
</map>

 <map> 标签:这个标签包裹了所有存储的键值对。它表示整个存储的数据集合。

 <string name="key">value</string>:用来存储 String 类型的数据。例如,dark_mode 被存储为 "true"(作为字符串)。

<boolean name="key">value</boolean>:存储 boolean 类型的数据,像 is_logged_in 被存储为 true

SharedPreferences 不能直接存储集合或数组,但它可以通过多次写入相同的键(如下例中的 favorite_colors)来模拟集合。每个 <string> 标签都是键为 favorite_colors 的一个值。

<?xml version="1.0" encoding="utf-8"?>
<map>
    <string name="favorite_colors">blue</string>
    <string name="favorite_colors">green</string>
    <string name="favorite_colors">red</string>
</map>

基于XM工格式的特点,共享参数主要用于如下场合:
(1)  简单且孤立的数据。若是复杂且相互关联的数据,则要保存在关系数据库中。
(2)  文本形式的数据。若是二进制数据,则要保存至文件。
(3)  需要持久化存储的数据。App退出后再次启动时,之前保存的数据仍然有效。 

二、实际存储案例

public class ShareWriteActivity extends AppCompatActivity implements View.OnClickListener, CompoundButton.OnCheckedChangeListener {
	private SharedPreferences mShared; // 声明一个共享参数对象
	private EditText et_name; // 声明一个编辑框对象
	private EditText et_age; // 声明一个编辑框对象
	private EditText et_height; // 声明一个编辑框对象
	private EditText et_weight; // 声明一个编辑框对象
	private boolean isMarried = false;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_share_write);
		et_name = findViewById(R.id.et_name);
		et_age = findViewById(R.id.et_age);
		et_height = findViewById(R.id.et_height);
		et_weight = findViewById(R.id.et_weight);
		CheckBox ck_married = findViewById(R.id.ck_married);
		ck_married.setOnCheckedChangeListener(this);
		findViewById(R.id.btn_save).setOnClickListener(this);
		// 从share.xml中获取共享参数对象
		mShared = getSharedPreferences("share", MODE_PRIVATE);
	}

	@Override
	public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
		isMarried = isChecked;
	}

	@Override
	public void onClick(View v) {
		if (v.getId() == R.id.btn_save) {
			String name = et_name.getText().toString();
			String age = et_age.getText().toString();
			String height = et_height.getText().toString();
			String weight = et_weight.getText().toString();
			if (TextUtils.isEmpty(name)) {
				ToastUtil.show(this, "请先填写姓名");
				return;
			} else if (TextUtils.isEmpty(age)) {
				ToastUtil.show(this, "请先填写年龄");
				return;
			} else if (TextUtils.isEmpty(height)) {
				ToastUtil.show(this, "请先填写身高");
				return;
			} else if (TextUtils.isEmpty(weight)) {
				ToastUtil.show(this, "请先填写体重");
				return;
			}
			
			SharedPreferences.Editor editor = mShared.edit(); // 获得编辑器的对象
			editor.putString("name", name); // 添加一个名叫name的字符串参数
			editor.putInt("age", Integer.parseInt(age)); // 添加一个名叫age的整型参数
			editor.putLong("height", Long.parseLong(height)); // 添加一个名叫height的长整型参数
			editor.putFloat("weight", Float.parseFloat(weight)); // 添加一个名叫weight的浮点数参数
			editor.putBoolean("married", isMarried); // 添加一个名叫married的布尔型参数
			editor.putString("update_time", DateUtil.getNowDateTime("yyyy-MM-dd HH:mm:ss"));
			editor.commit(); // 提交编辑器中的修改
			ToastUtil.show(this, "数据已写入共享参数");
		}
	}

}

活动页面对应的xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="5dp" >

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="40dp" >

        <TextView
            android:id="@+id/tv_name"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:gravity="center"
            android:text="姓名:"
            android:textColor="@color/black"
            android:textSize="17sp" />

        <EditText
            android:id="@+id/et_name"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_marginBottom="3dp"
            android:layout_marginTop="3dp"
            android:layout_toRightOf="@+id/tv_name"
            android:background="@drawable/editext_selector"
            android:gravity="left|center"
            android:hint="请输入姓名"
            android:inputType="text"
            android:maxLength="12"
            android:textColor="@color/black"
            android:textSize="17sp" />
    </RelativeLayout>

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="40dp" >

        <TextView
            android:id="@+id/tv_age"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:gravity="center"
            android:text="年龄:"
            android:textColor="@color/black"
            android:textSize="17sp" />

        <EditText
            android:id="@+id/et_age"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_marginBottom="3dp"
            android:layout_marginTop="3dp"
            android:layout_toRightOf="@+id/tv_age"
            android:background="@drawable/editext_selector"
            android:gravity="left|center"
            android:hint="请输入年龄"
            android:inputType="number"
            android:maxLength="2"
            android:textColor="@color/black"
            android:textSize="17sp" />
    </RelativeLayout>
    
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="40dp" >

        <TextView
            android:id="@+id/tv_height"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:gravity="center"
            android:text="身高:"
            android:textColor="@color/black"
            android:textSize="17sp" />

        <EditText
            android:id="@+id/et_height"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_marginBottom="3dp"
            android:layout_marginTop="3dp"
            android:layout_toRightOf="@+id/tv_height"
            android:background="@drawable/editext_selector"
            android:gravity="left|center"
            android:hint="请输入身高"
            android:inputType="number"
            android:maxLength="3"
            android:textColor="@color/black"
            android:textSize="17sp" />
    </RelativeLayout>
    
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="40dp" >

        <TextView
            android:id="@+id/tv_weight"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:gravity="center"
            android:text="体重:"
            android:textColor="@color/black"
            android:textSize="17sp" />

        <EditText
            android:id="@+id/et_weight"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_marginBottom="3dp"
            android:layout_marginTop="3dp"
            android:layout_toRightOf="@+id/tv_weight"
            android:background="@drawable/editext_selector"
            android:gravity="left|center"
            android:hint="请输入体重"
            android:inputType="numberDecimal"
            android:maxLength="5"
            android:textColor="@color/black"
            android:textSize="17sp" />
    </RelativeLayout>
    
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="40dp" >

        <CheckBox
            android:id="@+id/ck_married"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:gravity="center"
            android:checked="false"
            android:text="已婚"
            android:textColor="@color/black"
            android:textSize="17sp" />
    </RelativeLayout>
    
    <Button
        android:id="@+id/btn_save"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="保存到共享参数"
        android:textColor="@color/black"
        android:textSize="17sp" />

</LinearLayout>

 其实就是收集个人信息,并把个人信息以键值对的形式存储。

代码中需要学习的有以下几点:

mShared = getSharedPreferences("share", MODE_PRIVATE);

        1.这是 Android 中用于获取 SharedPreferences 的方法,作用是获取名为 "share" 的SharedPreferences 实例,用于存储和读取应用的键值对数据。

        2.由以上代码可知,getSharedPreferences方法的第一个参数是文件名,填share表示共享参数的文件名是share.xml;第二个参数是操作模式,填MODE PRIVATE表示私有模式,表示仅限当前应用访问(默认模式)

        3.在 Android 中使用 getSharedPreferences("share", MODE_PRIVATE) 方法时,不需要提前手动创建一个 share.xml 文件。Android 会自动处理该文件的创建。

        4.当你第一次调用 getSharedPreferences("share", MODE_PRIVATE) 时,Android 会在应用的默认存储目录中(通常是 /data/data/your.package.name/shared_prefs/)创建一个名为 share.xml 的文件。如果该文件已经存在,它将直接打开该文件用于读取或写入数据。

代码执行流程:

  1. 检查是否已有 "share.xml" 文件

    • 如果文件存在,则返回该 SharedPreferences 实例,并可以读取其中的数据。
    • 如果文件不存在,则自动创建一个新文件(但不会立刻写入数据,只有在 apply()commit() 时才写入)。这个文件是存储在用户手机内的。
  2. 返回 SharedPreferences 对象

    • 这个对象提供 getXXX() 方法(如 getString()getBoolean()),用于读取存储的数据。

        另外注意上述代码采用了commit方法提交修改,该方法会把数据直接写入磁盘。如果想要更好的性能,可将commit方法改为apply方法,该方法的提交操作会先将数据写入内存,然后异步把数据写入磁盘。

三、效果展示

点击保存,所有数据会以commit的方式提交写入手机磁盘。

四、读取数据

@SuppressLint("DefaultLocale")
public class ShareReadActivity extends AppCompatActivity {
    private TextView tv_share; // 声明一个文本视图对象

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_share_read);
        tv_share = findViewById(R.id.tv_share);
        readSharedPreferences(); // 从共享参数中读取信息
    }

    // 从共享参数中读取信息
    private void readSharedPreferences() {
        // 从share.xml中获取共享参数对象
        SharedPreferences shared = getSharedPreferences("share", MODE_PRIVATE);
        String desc = "共享参数中保存的信息如下:";
        // 获取共享参数保存的所有映射配对信息
        Map<String, Object> mapParam = (Map<String, Object>) shared.getAll();
        // 遍历该映射对象,并将配对信息形成描述文字
        for (Map.Entry<String, Object> item_map : mapParam.entrySet()) {
            String key = item_map.getKey(); // 获取该配对的键信息
            Object value = item_map.getValue(); // 获取该配对的值信息
            if (value instanceof String) { // 如果配对值的类型为字符串
                desc = String.format("%s\n %s的取值为%s", desc, key,
                        shared.getString(key, ""));
            } else if (value instanceof Integer) { // 如果配对值的类型为整型数
                desc = String.format("%s\n %s的取值为%d", desc, key,
                        shared.getInt(key, 0));
            } else if (value instanceof Float) { // 如果配对值的类型为浮点数
                desc = String.format("%s\n %s的取值为%f", desc, key,
                        shared.getFloat(key, 0.0f));
            } else if (value instanceof Boolean) { // 如果配对值的类型为布尔值
                desc = String.format("%s\n %s的取值为%b", desc, key,
                        shared.getBoolean(key, false));
            } else if (value instanceof Long) { // 如果配对值的类型为长整型
                desc = String.format("%s\n %s的取值为%d", desc, key,
                        shared.getLong(key, 0L));
            } else { // 如果配对值的类型为未知类型
                desc = String.format("%s\n参数%s的取值为未知类型", desc, key);
            }
        }
        if (mapParam.size() <= 0) {
            desc = "共享参数中保存的信息为空";
        }
        tv_share.setText(desc);
    }

}

 重点是下面的代码,从共享对象中获取所有配置信息。

Map<String, Object> mapParam = (Map<String, Object>) shared.getAll();

运行之后可以得到 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

国自然专项项目申请:AI赋能的急性心肌梗死预警研究|基金申请·25-02-14

小罗碎碎念 急性心肌梗死严重威胁生命健康&#xff0c;因其起病隐匿、发病机制复杂&#xff0c;早期预警困难。现在&#xff0c;转机来了&#xff01;国自然“AI赋能的急性心肌梗死预警研究”专项项目2025年度指南重磅发布。 该项目致力于攻克难题&#xff0c;通过多学科交叉…

【鸿蒙开发】第二十八章 应用状态的讲解、状态持久化、网络管理、应用数据持久化、文件上传下载

目录 1 应用状态 1.1 LocalStorage&#xff1a;页面级UI状态存储 1.1.1 两个页面共享一个对象 1.1.2 页面间共享 1.1.3 应用逻辑中使用 1.2 AppStorage&#xff1a;应用全局的UI状态存储 1.2.1 概述 1.2.2 基本用法 1.2.3 经常使用的方法 1.3 PersistentStorage&#x…

学习threejs,使用HemisphereLight半球光

&#x1f468;‍⚕️ 主页&#xff1a; gis分享者 &#x1f468;‍⚕️ 感谢各位大佬 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍⚕️ 收录于专栏&#xff1a;threejs gis工程师 文章目录 一、&#x1f340;前言1.1 ☘️THREE.HemisphereLight 二、…

数仓:核心概念,数仓系统(ETL,数仓分层,数仓建模),数仓建模方法(星型模型,雪花模型,星座模型)和步骤

数仓建模的核心概念 事实表&#xff08;Fact Table&#xff09;&#xff1a; 存储业务过程的度量值&#xff08;如销售额、订单数量等&#xff09;。 通常包含外键&#xff0c;用于关联维度表。 维度表&#xff08;Dimension Table&#xff09;&#xff1a; 存储描述性信息&…

python 基础知识100问

目录 1 Python中函数的输入参数类型‌&#xff1a; 2 python 第一个方法参数 selt cls 3 类和面向对象 4 Python 中__init__.py 作用 5 python 元类与装饰器 元类与装饰器https://blog.csdn.net/qq_52213943/article/details/145175689?spm1001.2014.3001.5506 6 设…

如何使用 DeepSeek R1 构建开源 ChatGPT Operator 替代方案

开源大型语言模型&#xff08;LLMs&#xff09;的兴起使得创建 AI 驱动的工具比以往任何时候都更容易&#xff0c;这些工具可以与 OpenAI 的 ChatGPT Operator 等专有解决方案相媲美。在这些开源模型中&#xff0c;DeepSeek R1 以其强大的推理能力、自由的可访问性和适应性而脱…

【教程】MySQL数据库学习笔记(七)——多表操作(持续更新)

写在前面&#xff1a; 如果文章对你有帮助&#xff0c;记得点赞关注加收藏一波&#xff0c;利于以后需要的时候复习&#xff0c;多谢支持&#xff01; 【MySQL数据库学习】系列文章 第一章 《认识与环境搭建》 第二章 《数据类型》 第三章 《数据定义语言DDL》 第四章 《数据操…

Word 公式转 CSDN 插件 发布

经过几个月的苦修&#xff0c;这款插件终于面世了。 从Word复制公式到CSDN粘贴&#xff0c;总是出现公式中的文字被单独提出来&#xff0c;而公式作为一个图片被粘贴的情况。公式多了的时候还会导致CSDN禁止进一步的上传公式。 经过对CSDN公式的研究&#xff0c;发现在粘贴公…

【ESP32接入国产大模型之Deepseek】

【ESP32接入国产大模型之Deepseek】 1. Deepseek大模型1.1 了解Deepseek api1.2 Http接口鉴权1.3. 接口参数说明1.3.1 请求体(request)参数1.3.2 模型推理 2. 先决条件2.1 环境配置2.2 所需零件 3. 核心代码3.1 源码分享3.2 源码解析3.3 连续对话修改后的代码代码说明示例输出注…

C语言蓝桥杯1003: [编程入门]密码破译

要将"China"译成密码&#xff0c;译码规律是&#xff1a;用原来字母后面的第4个字母代替原来的字母&#xff0e; 例如&#xff0c;字母"A"后面第4个字母是"E"&#xff0e;"E"代替"A"。因此&#xff0c;"China"应译…

SolidWorks速成教程P3-3【零件 | 第三节】——草图绘制面实线与构造线的区别

经过了前面的特征学习后,是不是感觉对 SolidWorks越来越熟悉了?不过发现, SolidWorks速成这套教程,对于一些基础问题,还是需要解释得更详细一些,所以在这节再补充一下草图绘制面&实线与构造线的区别。 目录 1.草图绘制面 2.实线与构造线的区别 1.草图绘制面 之前…

win10中mstsc远程Centos-Stream 9图形化界面

文章目录 1 前置状态2 安装配置XRDP3 关闭SELinux3.1 查看selinux状态3.2 关闭selinux 4 启动XRDP5 Win10远程连接测试 1 前置状态 已安装CentOS9桌面版&#xff1b;Windows10。 2 安装配置XRDP sudo yum install epel-release sudo yum install xrdp sudo yum install tige…

中国AI“拥抱开源”给世界的启示——Anko

事实证明&#xff0c;中国AI企业“拥抱开源”&#xff0c;不仅为自身发展开拓了新路径&#xff0c;也带动AI企业跨国合作的需求&#xff0c;并推动全球AI生态向“开源普惠”转型。Anko通过免费开放部分模型功能&#xff0c;将AI时代的数字红利公平地派发到每一位网民手中&#…

DeepSeek处理自有业务的案例:让AI给你写一份小众编辑器(EverEdit)的语法着色文件

1 DeepSeek处理自有业务的案例&#xff1a;让AI给你写一份小众编辑器(EverEdit)的语法着色文件 1.1 背景 AI能力再强&#xff0c;如果不能在企业的自有业务上产生助益&#xff0c;那基本也是一无是处。将企业的自有业务上传到线上训练&#xff0c;那是脑子进水的做法&#xff…

Jenkins 配置 Git Parameter 四

Jenkins 配置 Git Parameter 四 一、开启 项目参数设置 勾选 This project is parameterised 二、添加 Git Parameter 如果此处不显示 Git Parameter 说明 Jenkins 还没有安装 Git Parameter plugin 插件&#xff0c;请先安装插件 Jenkins 安装插件 三、设置基本参数 点击…

网络工程师 (38)流量和差错控制

一、流量控制 流量控制是一种协调发送站和接收站工作步调的技术。它的主要目的是防止发送端发送数据过快&#xff0c;导致接收端缓冲区溢出&#xff0c;从而造成数据丢失。流量控制机制通过调整发送速率来匹配接收端的处理能力。 基本原理 发送站每发出一帧数据&#xff0c;就进…

从零开始:Django初学者的实战之旅

一、概念引入 要基于编程开发一个完整的企业项目不管什么样的项目&#xff0c;基本都有3种不同的开发模式&#xff0c;这几种开发模式&#xff0c;如果把项目类比成建造房子则有如下&#xff1a; 1.原生开发&#xff1a;类似从0开始造房子&#xff0c;从0开始构建项目&#xf…

青果教务系统逆向(js逆向)

首先我们打开f12检查以下登录函数 可以看到登录函数在checkrand中&#xff0c;直接去全局搜索函数 在这里&#xff0c;打个断点直接跳进去 可以看到参数在这里形成 这是我们发起请求需要的参数&#xff0c;把这几个参数加进去直接登录就行 那就一个一个看呗&#xff0c;第一…

在Linux中Redis不支持lua脚本的处理方法

redis安装在IP为x.x.x.x的服务器上 redis安装 第一步&#xff0c;安装前&#xff0c;检测系统是否安装了redis。若安装了redis&#xff0c;则需要删除redis&#xff1b;若没有安装redis&#xff0c;则需要安装2.6版本以上的redis。 # 确保Redis版本支持Lua脚本。从Redis 2.6…

WPF进阶 | 深入 WPF 依赖项属性:理解其强大功能与应用场景

WPF进阶 | 深入 WPF 依赖项属性&#xff1a;理解其强大功能与应用场景 前言一、依赖项属性基础概念1.1 什么是依赖项属性1.2 依赖项属性与 CLR 属性的区别1.3 依赖项属性的定义与注册 二、依赖项属性的原理深入剖析2.1 依赖项属性系统的工作机制2.2 元数据&#xff08;Metadata…