Android SharedPreferences数据存储原理解析及使用示例

刘氏一键拨号app的SharedPreferences数据存储技术深度解析 在Android开发中,是一种轻量级的存储解决方案,通常用于保存应用的用户偏好设置,如主题选择、登录状态等简单的配置信息。它提供了基本的数据存储机制,包括数据的保存、读取、修改以及删除等操作。 阅读详情
一、SharedPreferences简介

    SharedPreferences是基础key-value(键值对)来存储一些轻量数据的存储方式,特别适用于保存软件配置参数。使用SharedPreferences 保存数据,其背后是用xml文件存放数据,文件存放在/data/data/<package name>/shared_prefs。

SharedPreferences主要特点:
- 适合于少量数据的保存 ;
- 保存的数据只支持Java基本数据类型,不支持自定义数据类型;
- 使用简单。

二、使用方法
1)获取SharedPreferences实例

    SharedPreferences本身是一个接口,程序无法直接创建SharedPreferences实例,只能通过Context提供的getSharedPreferences(String name,int mode)方法来获取SharedPreferences实例。例如:

// 获取只能被本应用程序读、写的SharedPreferences对象
SharedPreferences preferences = getSharedPreferences("sharedPrefFile", Context.MODE_PRIVATE);

    第一个参数是生成xxx.xml文件的文件名字,第二个参数是文件的访问权限以及文件数据写入方式。

简单说明一下几种方式:
Context.MODE_PRIVATE: //指定该SharedPreferences数据只能被本应用程序读写。
Context.MODE_WORLD_READABLE: //指定该SharedPreferences数据能被其他应用程序读,但不能写。
Context.MODE_WORLD_WRITEABLE: //指定该SharedPreferences数据能被其他应用程序读写。

注意:从Android4.2开始, Android不再推荐使用 MODE_WORLD_READABLE、MODE_WORLD_WRITEABLE这两种模式, 因为这两种模式允许其他应用程序来读或写本应用创建的数据, 因此容易导致安全漏洞 。 如果应用程序确实需要把内部数据暴露出来供其他应用访司, 则应该使用 ContentProvider。

2)写入数据

方法一:

//获取SharedPreferences实例
SharedPreferences preferences = getSharedPreferences("sharedPrefFile", Context.MODE_PRIVATE);
//实例化SharedPreferences.Editor对象
editor = preferences.edit();
// 存入用户姓名
editor.putString("name", "yourname");
//存入用户年龄             
editor.putInt("age",18);
// 提交所有存入的数据
editor.commit();

方法二:

SharedPreferences preferences = getSharedPreferences("sharedPrefFile", Context.MODE_PRIVATE);
preferences.edit()
.putString("name",  "yourname")
.putInt("age", 18)
.commit();

切记:不要写成下面的形式,会导致数据无法存储。

SharedPreferences sp = getSharedPreferences("sharedPrefFile", Context.MODE_PRIVATE);
sp.edit().putString("name", "yourname");
sp.edit().putInt("age", 18);
sp.edit().commit();

    为什么这种方式无法存储? 因为sp.edit()每次都会返回一个新的Editor对象,Editor的实现类EditorImpl里面会有一个缓存的Map,最后commit的时候先将缓存里面的Map写入内存中的Map,然后将内存中的Map写进XML文件中。使用上面的方式commit,由于sp.edit()又重新返回了一个新的Editor对象,缓存中的Map是空的,所以导致数据无法被存储。

3)读取数据
//获取SharedPreferences实例
SharedPreferences preferences = getSharedPreferences("sharedPrefFile", Context.MODE_PRIVATE);
// 读取字符串数据
String name = preferences.getString("name", "");
// 读取int类型的数据
int age = preferences.getInt("age", 0);

    getSharedPreferences的具体实现是frameworks/base/core/java/android/app/ContextImpl.java,代码如下:

@Override
public SharedPreferences getSharedPreferences(String name, int mode) {
    SharedPreferencesImpl sp;
    synchronized (ContextImpl.class) {
        ......
        final String packageName = getPackageName();
        ArrayMap<String, SharedPreferencesImpl> packagePrefs = sSharedPrefs.get(packageName);
        if (packagePrefs == null) {
            packagePrefs = new ArrayMap<String, SharedPreferencesImpl>();
            sSharedPrefs.put(packageName, packagePrefs);
        }

        ......
        sp = packagePrefs.get(name);
        if (sp == null) {
            File prefsFile = getSharedPrefsFile(name);
            sp = new SharedPreferencesImpl(prefsFile, mode);
            packagePrefs.put(name, sp);
            return sp;
        }
    }
    ......
    return sp;
}

    SharedPreferencesImpl是SharedPreferences接口的具体实现类,一个name对应一个SharedPreferencesImpl,一个应用程序中根据name的不同会有多个SharedPreferencesImpl。
SharedPreferencesImpl的具体实现是在frameworks/base/core/java/android/app/SharedPreferencesImpl.java,我们可以通过getSharedPreferences获得SharedPreferences的实例,当我们调用sp.getString等get方法取数据时,实际上是直接从内存中的Map里面去取,get方法传入的第一个参数正好是Map的key,第二个参数是当Map中没有这个key对应值的时候,返回的默认值。

4)监听数据变化
SharedPreferences.OnSharedPreferenceChangeListener onSharedPreferenceChangeListener = new SharedPreferences.OnSharedPreferenceChangeListener() {
            @Override
            public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {

            }
        };
        preferences.registerOnSharedPreferenceChangeListener(onSharedPreferenceChangeListener);//注册数据变化监听
        preferences.unregisterOnSharedPreferenceChangeListener(onSharedPreferenceChangeListener);//解注册数据变化监听
5)具体写入文件的存储结构

这里写图片描述

    存储在文件中就是这样的,纯明文存储没有一点安全性可言。即使设置了Activity.MODE_PRIVATE权限在ROOT权限面前也是不堪一击的。所以我们在使用SharedPreferences的时候尽量不要存储一些有关用户信息的数据,如果要存储那该怎么补救呢?我们可以把key和value的值采用加密算法加密一下。

三、使用示例

    简单设计一个应用,让用户输入姓名和年龄,然后将数据保存到SharedPreferences,之后读取SharedPreferences数据并在界面上显示出来。当用户修改数据重新保存以后,提示SharedPreferences数据发生变化。界面如下图:

这里写图片描述

首先是布局文件,

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingTop="50dp"
    android:paddingLeft="100dp">
    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/name"
            android:textAppearance="?android:attr/textAppearanceLarge"/>
        <EditText
            android:id="@+id/etWriteName"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="@string/write_name"
            android:textAppearance="?android:attr/textAppearanceLarge"/>
    </LinearLayout>
    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/age"
            android:textAppearance="?android:attr/textAppearanceLarge"/>
        <EditText
            android:id="@+id/etWriteAge"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="@string/write_age"
            android:textAppearance="?android:attr/textAppearanceLarge"/>
    </LinearLayout>
    <Button
        android:id="@+id/write"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/write"
        android:textAppearance="?android:attr/textAppearanceLarge"/>
    <Button
        android:id="@+id/read"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/read"
        android:textAppearance="?android:attr/textAppearanceLarge"/>
    <TextView
        android:id="@+id/tvReadData"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceLarge"/>
</LinearLayout>

然后是主程序代码,

package cl.fjnu.edu.cn.sharedpreferencestest;

import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity
{
    SharedPreferences preferences;
    SharedPreferences.Editor editor;
    private EditText etWriteName;
    private EditText etWriteAge;
    private TextView tvRead;
    private Button read;
    private Button write;
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        etWriteName = (EditText) findViewById(R.id.etWriteName);
        etWriteAge = (EditText) findViewById(R.id.etWriteAge);
        tvRead = (TextView) findViewById(R.id.tvReadData);
        write = (Button) findViewById(R.id.write);
        read = (Button) findViewById(R.id.read);

        //获取只能被本应用程序读写的SharedPreferences对象,
        //保存的文件名为sharedPrefFile.xml
        preferences = getSharedPreferences("sharedPrefFile", Context.MODE_PRIVATE);
        //实例化SharedPreferences.Editor对象
        editor = preferences.edit();
        //注册数据变化监听
        preferences.registerOnSharedPreferenceChangeListener(
      onSharedPreferenceChangeListener);

        write.setOnClickListener(new OnClickListener()
        {
            @Override
            public void onClick(View arg0)
            {
                // 存入用户姓名
                editor.putString("name", etWriteName.getText().toString());
                //存入用户年龄
                editor.putInt("age",Integer.parseInt(etWriteAge.getText().toString()));
                // 提交所有存入的数据
                editor.commit();
            }
        });

        read.setOnClickListener(new OnClickListener()
        {
            @Override
            public void onClick(View arg0)
            {
                // 读取字符串数据
                String name = preferences.getString("name", "");
                // 读取int类型的数据
                int age = preferences.getInt("age", 0);
                //显示读取出来的数据
                tvRead.setText("姓名: "+name+"\n年龄: "+age);
            }
        });

    }

    //数据变化监听器
    SharedPreferences.OnSharedPreferenceChangeListener onSharedPreferenceChangeListener
            = new SharedPreferences.OnSharedPreferenceChangeListener() {
        @Override
        public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
            Toast.makeText(MainActivity.this,"sharedPrefTest文件数据发生了变化!",Toast.LENGTH_SHORT).show();
        }
    };

}

运行效果:

    在姓名和年龄输入框分别输入数据,然后点击保存数据,再读取数据,可以看到下方显示出用户保存的SharedPreferences数据。如下图,

这里写图片描述

    修改输入数据,点击保存数据重新保存,则弹出Toast消息,提示SharedPreferences数据已发生变化。如下图所示,

这里写图片描述

    此时再点击读取数据,则会显示出更新过的SharedPreferences数据。如下图,

这里写图片描述

Linux下开机异常(fsck exited with status code 4) Linux下开机异常事情是这样的,本来我呢跑着程序听着歌,结果忽然就死机了,我只能强制关机,再次打开系统的时候,就提示这样fsck from util-linux 2.26.2 /dev/sda10 contains a file system with errors, check forced. /dev/sda10: Inodes that were part of a corrupted pr 阅读详情

相关推荐

SharedPreferences数据存储原理解析

SharedPreferences简介 SharedPreferences是基于key-value(键值对)来存储一些轻量数据的存储方式,实质是用xml文件存放数据,文件存放在/data/data//shared_prefs,适用于保存软件配置参数。 使用方式 写入 SharedPreferences preferences = getSharedPreferences("sharedPrefFile", Context.MODE_PRIVATE); preferences.edit().putString

雨汨的博客 1054

达梦慢sql和统计信息收集

各计划节点的执行顺序为:缩进越多的越先执行,同样缩进的上面的先执行,下面的后执行,上下的优先级高于内外。在建立索引的时候,要考虑索引的最左匹配原则(在使用 SQL 语句时,如果 where 部分的条件不符合最左匹配原则,可能导致索引失效,或者不能完全发挥建立的索引的功效);执行计划是 SQL 语句的执行方式,由查询优化器为语句设计的执行方式,交给执行器去执行。生产系统中,对于频繁变动的数据表,多次执行计划可能会出现不一致的问题,这往往是由于统计信息不准导致的,索引定期收集统计信息就很有必要了。

m0_37680131的博客 1713

移动设备软件开发回顾---SharedPreferences

SharedPreference的简单使用

简单点的博客 1232

从驱动编译到数据传输:RK3588与FPGA的PCIe通信实战解析

本文详细解析了RK3588与FPGA通过PCIe通信的实战过程,涵盖驱动编译、数据传输及性能优化等关键步骤。通过XDMA驱动实现高效DMA传输,适用于视频处理、数据采集等高性能场景,帮助开发者快速掌握嵌入式系统中的PCIe通信技术。

weixin_29214691的博客 521

银河麒麟V10+QT6.0中文输入法环境搭建全攻略(附镜像加速技巧)

本文提供了在银河麒麟V10操作系统上为QT6.0搭建中文输入法环境的完整实战指南。文章详细介绍了从系统准备、镜像源优化、QT6安装器获取与加速安装,到编译Fcitx5输入法插件依赖库、深度配置环境变量与项目的全流程。重点分享了使用国内镜像源加速安装的技巧,解决了国产化开发中QT应用无法输入中文的常见难题,旨在帮助开发者快速构建稳定高效的开发环境。

weixin_29204749的博客 392

Android 入门第七讲02-SharedPreferences(SharedPreferences概述,使用方法(写数据+读数据),实战案例-qq登录demo)

Android 入门第七讲02-数据库 Android 入门第七讲01-数据存储(数据存储概述,文件存储(raw和asserts目录读写,data/data/包名目录读写,sdcard目录读写),SharedPreferences读写)

Rose J 的博客 1686

基于XDMA 的PCIE读写DDR

基于XDMA 的PCIE读写DDR 概述:   想实现基于FPGA的PCIe通信,查阅互联网各种转载…基本都是对PCIe的描述,所以想写一下基于XDMA的PCIe通信的实现(PCIe结构仅做简单的描述(笔记),了解详细结构移至互联网)。 实现功能:PC通过PCIE读写DDR,同时用户通过逻辑代码可以读取被写入DDR内的数据(我是通过VIO实现DDR任意地址,任意数据大小的读取。)。 实践实践!!! 说明: 参考文档: PCI Express Base Specification Revision 3.0 P

Crazzy_M的博客 1万+

SharedPreferences原理及相关分析

问: 1、 听说提交要用apply(),为什么? 2、和commit()什么区别? 3、跨进程怎么操作? 4、会堵塞主线程吗? 5、很着急有替代方案吗? 一、加载/初始化 一切从getSharedPreference(String name,int Mode)这个方法说起;通过这个方法获取到一个SharedPreference实例。SharedPreferences是一个接口(interface),他的具体实现类为SharedPreferencesImpl。 SharedPreference的加载的主要

u013750244的博客 1352

深度拆解 ‘High-Frequency Trading’ (HFT) 系统:解析如何在 100 纳秒内完成从网卡到 C++ 策略的响应

在100纳秒内完成从网卡到C++策略的响应,这是一项对技术栈每一个层面都进行极限优化的系统工程。它要求我们深入理解计算机体系结构、操作系统、网络协议和C++语言的底层机制。从物理距离的极致缩短,到高性能网卡和内核旁路技术,再到C++代码中每一个字节、每一个CPU周期的精打细算,HFT系统展现了人类对计算速度的永恒追求。这项技术不仅仅应用于金融交易,其背后的低延迟理念和实现方法,如DPDK、无锁编程、硬件加速等,正在逐渐渗透到其他对延迟敏感的领域,例如电信网络、边缘计算和工业自动化。

weixin_41455464的博客 1039

8、 使用TPM密钥:从理论到实践的全面指南

本文全面介绍了如何使用TPM(可信平台模块)进行密钥管理,涵盖密钥的创建、存储、加载、迁移以及特殊密钥类型的使用。通过详细的操作步骤和代码示例,帮助读者掌握TPM密钥管理技术,确保系统的安全性和可靠性。

weixin_36212459的博客 242

关于跨应用读取程序的SharedPreferences

android中读取其他应用数据的使用比较多,最常见的就是ContentProvider,比如联系人。如果我们只需获取一两个值

tianshi4851的专栏 3968

用 CDS 作为 Referenced Data Source 开发 SAP Gateway OData 服务,一条更轻的 SEGW 路线

本文介绍了SAP Gateway项目中从传统手工建模到基于CDS View的现代化开发方式转变。主要内容包括: 传统方式需要在SEGW中手动创建Entity Type、Entity Set等元素,并在DPC_EXT中编写大量查询逻辑,存在模型层和业务逻辑重复表达的问题。 7.50版本后,SAP Gateway与ABAP CDS深度集成,可通过SEGW直接引用CDS View作为数据源,自动生成数据模型和SADL读取逻辑,支持完整的OData查询功能。 最佳实践建议通过Consumption View而非直接

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 700

深入解析 SharedPreferences

一. 概述 SharedPreferences 是Android中很常用的数据存储方式,SP 采用 key-value形式, 主要用于: 轻量级的数据存储, 尤其适合保存应用的配置参数 不建议使用SP 来存储大规模的数据, 可能会降低性能 SP 采用 xml 文件格式来保存数据, 该文件所在目录位于 /data/data//shared_prefs/ 1.1 使用示例 SharedPrefe...

怪咖先森的博客 1059

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

Android数据存储原理分析

  Android上常见的数据存储方式为:   SharedPreferences是 Android 中比较常用的存储方法,本篇将从源码角度带大家分析一下Android中常用的轻量级数据存储工具SharedPreferences。   1.什么是SharedPreferences?官方说法为:   它可以用来存储一些比较小的键值对集合;   对于任何一类的preference,S...

weixin_30549657的博客 212

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

Android SharedPreferences解析

SharedPreferences解析

zq2114522的专栏 1092

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

android学习笔记之轻量级存储SharedPreferences

SharedPreferences是一个接口,以下是android对此接口的官方介绍(用的geogle翻译) api翻译:用于访问和修改所返回的首选项数据的接口Context#getSharedPreferences。对于任何特定的首选项集,所有客户端都共享一个此类的单个实例。对首选项的修改必须经过一个Editor对象,以确保首选项值保持一致状态并控制将它们提交到存储时的状态。从各种get方法返回...

晓晓的博客 1464

SharedPreferences总结

前言: SharedPreferences很早就用过,但也只限于会用,隔了一段时间再用发现有点生疏,还是要去网上找用法,对其运行原理和不同方法间的区别也知之甚少,决定写一篇文章来总结一下,加深下印象和理解。 概述: SharedPreferences是Android提供的几种常用的数据存储解决方案之一,应用可以通过它来访问和修改一些他们所关注的数据,常被用来存储少量的、格式简单的

Peter的专栏 758

深入理解Android中的SharedPreferences

深入理解Android中的SharedPreferences

未来很长,但我会努力的走下去。 1542

Android知识点(六)之数据存储

Android系统中主要提供了3种方式用于简单地实现数据持久化功能,即文件存储、SharedPreferences存储以及数据库存储,真机测试是没有办法通过File Provider查看保存的数据的。 数据存储方式 文件保存目录 File /data/data/< 包名>/files/< 文件名> sharedPreferences /data/data/< 包名>/shared_prefs/< 文件名> SQLite /data/da

梵高话葵 543

SharedPreferences

除了SQLite数据库外,SharedPreferences也是一种轻型的数据存储方式,它的本质是基于XML文件存储key-value键值对数据,通常用来存储一些简单的配置信息。其存储位置在/data/data//shared_prefs目录下。SharedPreferences对象本身只能获取数据而不支持存储和修改,存储修改是通过Editor对象实现。实现SharedPreferences存储的

风华绝代 718

Android SharedPreferences实战指南

摘要:本文详细介绍了Android中SharedPreferences的使用方法,包括数据存储原理、读写操作和实际应用案例。SharedPreferences适合存储少量配置数据(如用户名、密码等),通过键值对形式保存为XML文件。文章通过一个简单Demo演示了数据读写过程,并重点讲解了如何实现QQ登录页的"记住密码"功能。该功能通过SharedPreferences保存用户登录状态和账号信息,在应用重启时自动填充。文末还解答了常见问题,并强调SharedPreferences仅适用于轻

2301_80194233的博客 1340

Android数据存储五种方式总结

本文介绍Android平台进行数据存储的五大方式,分别如下:        1 使用SharedPreferences存储数据     2 文件存储数据           3 SQLite数据库存储数据     4 使用ContentProvider存储数据     5 网络存储数据 下面详细讲解这五种方式的特点 第一种: 使用SharedPrefe

梦想 坚持 自由 2002

SharedPreferences源码之我见

说在前面:SharedPreferences是Android中几种重要的存储数据的方式,Android开发不会没有人从来没有使用过,但是却很好人会关注它是怎么实现的,确实SharedPreferences实现起来比较简单,本质是基于文件存储,格式是XML形势的,本篇文章并没有太深的技术,但绝对是不可缺少的知识。 概述 SharedPref...

weixin_34268753的博客 72

Android 数据存储方式深度解析

Android 提供了多种数据存储方案,每种方案都有其特定的使用场景和优缺点。

斗锋在干嘛的博客 820

Android面试题-----SharedPreferences的底层实现是什么?SharedPreferences是否支持多线程?

出处:2019年某司秋招题 问题链接:本人在笔试中遇到的,不便透露公司 参考文章:https://blog.youkuaiyun.com/wk_beicai/article/details/78523449 https://www.cnblogs.com/mzhou/p/3941008.html --------------------------------------...

陈某狗 3906
上一篇: Android自定义PreferenceCategory的title颜色、字体大小写的方法
下一篇: 深入理解SQL的四种连接-左外连接、右外连接、内连接、全外连接
Lois00
博客等级 码龄11年 4粉丝 13原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值