Android Studio:键值对存储sharedPreferences

news/2025/2/15 9:05:56/

一、了解 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;@Overrideprotected 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);}@Overridepublic void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {isMarried = isChecked;}@Overridepublic 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" ><RelativeLayoutandroid:layout_width="match_parent"android:layout_height="40dp" ><TextViewandroid: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" /><EditTextandroid: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><RelativeLayoutandroid:layout_width="match_parent"android:layout_height="40dp" ><TextViewandroid: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" /><EditTextandroid: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><RelativeLayoutandroid:layout_width="match_parent"android:layout_height="40dp" ><TextViewandroid: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" /><EditTextandroid: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><RelativeLayoutandroid:layout_width="match_parent"android:layout_height="40dp" ><TextViewandroid: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" /><EditTextandroid: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><RelativeLayoutandroid:layout_width="match_parent"android:layout_height="40dp" ><CheckBoxandroid: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><Buttonandroid: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; // 声明一个文本视图对象@Overrideprotected 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.ppmy.cn/news/1572197.html

相关文章

基础算法 高精度运算 #大数加法

文章目录 题目链接题目解读完整代码参考 题目链接 题目解读 题目描述 输入两个正整数a,b&#xff0c;输出ab的值。 输入格式 两行&#xff0c;第一行a&#xff0c;第二行b。a和b的长度均小于1000位。 输出格式 一行&#xff0c;ab的值。 完整代码 #include<bits/stdc.h&…

Java 大视界 -- 大数据伦理与法律:Java 技术在合规中的作用与挑战(87)

&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎来到 青云交的博客&#xff01;能与诸位在此相逢&#xff0c;我倍感荣幸。在这飞速更迭的时代&#xff0c;我们都渴望一方心灵净土&#xff0c;而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识&#xff0c;也…

DeepSeekApi对接流式输出异步聊天功能:基于Spring Boot和OkHttp的SSE应用实现

实现异步聊天功能&#xff1a;基于Spring Boot和OkHttp的SSE应用 在现代Web应用程序开发中&#xff0c;实时更新的能力对于增强用户体验至关重要。本文将详细介绍如何利用Spring Boot框架结合OkHttp库实现一个简单的异步聊天服务&#xff0c;该服务能够接收用户输入并通过Serv…

原生Three.js 和 Cesium.js 案例 。 智慧城市 数字孪生常用功能列表

对于大多数的开发者来言&#xff0c;看了很多文档可能遇见不到什么有用的&#xff0c;就算有用从文档上看&#xff0c;把代码复制到自己的本地大多数也是不能用的&#xff0c;非常浪费时间和学习成本&#xff0c; 尤其是three.js &#xff0c; cesium.js 这种难度较高&#xff…

【2025深度学习系列专栏大纲:深入探索与实践深度学习】

第一部分:深度学习基础篇 第1章:深度学习概览 1.1 深度学习的历史背景与发展轨迹 1.2 深度学习与机器学习、传统人工智能的区别与联系 1.3 深度学习的核心组件与概念解析 神经网络基础 激活函数的作用与类型 损失函数与优化算法的选择 1.4 深度学习框架简介与选择建议 第2…

如何在 Visual Studio Code 中使用 DeepSeek R1 和 Cline?

让我们面对现实吧&#xff1a;像 GitHub Copilot 这样的 AI 编码助手非常棒&#xff0c;但它们的订阅费用可能会在你的钱包里烧一个洞。进入 DeepSeek R1 — 一个免费的开源语言模型&#xff0c;在推理和编码任务方面可与 GPT-4 和 Claude 3.5 相媲美。将它与 Cline 配对&#…

基于springboot 以及vue前后端分离架构的求职招聘系统设计与实现

基于springboot 以及vue前后端分离架构的求职招聘系统设计与实现 随着互联网技术的飞速发展&#xff0c;求职招聘行业也在不断发生变革。传统的求职招聘方式往往存在着信息不对称、效率低下、交易成本高等问题&#xff0c;导致企业的招聘成本增加&#xff0c;求职者的体验下降…

盛铂科技 SMF106 低相位噪声贴片式频率综合器模块

在现代通信和电子设备领域&#xff0c;频率综合器作为关键组件&#xff0c;其性能优劣直接影响系统的整体表现。盛铂科技的 SMF106 低相位噪声贴片式频率综合器&#xff0c;以其卓越的性能和独特设计&#xff0c;成为众多高性能系统的选择。 一、频率覆盖范围广&#xff0c;步进…