Android SharedPreferences数据存储详解

目录
  • 前言
  • SharedPreferences
  • Editor
  • 性能和技巧
  • 示例代码

前言

Android提供了很多种保存应用程序数据的方法。其中一种就是用SharedPreferences对象来保存我们私有的键值(key-value)数据。

所有的逻辑都是基于下面三个类:

  • SharedPreferences
  • SharedPreferences.Editor
  • SharedPreferences.OnSharedPreferenceChangeListener

SharedPreferences

SharedPreferences是其中最重要的。它负责获取(解析)存储的数据,提供获取Editor对象的接口和添加或移除OnSharedPreferenceChangeListener的接口。

  • 创建SharedPreferences你需要Context对象(也可以是application Context)
  • getSharedPreferences方法会解析Preference文件并为它创建一个Map对象
  • 你可以用Context提供的几个模式创建它,强烈建议使用MODE_PRIVATE模式因为创建全局可读写的文件是比较危险的,可能会导致app的安全漏洞。
  / parse Preference file 解析Preference文件
  SharedPreferences preferences = context.getSharedPreferences("com.example.app", Context.MODE_PRIVATE);
  // get values from Map
  preferences.getBoolean("key", defaultValue)
  preferences.get..("key", defaultValue)
  // you can get all Map but be careful you must not modify the collection returned by this
  // method, or alter any of its contents.
  //(Preference文件转换成map)你可以获取到一个map但是小心点最好不要修改map或它的内容
  Map<String, ?> all = preferences.getAll();
  // get Editor object
  SharedPreferences.Editor editor = preferences.edit();
  // add on Change Listener 添加监听器
  preferences.registerOnSharedPreferenceChangeListener(mListener);
  // remove on Change Listener 取消监听器
  preferences.unregisterOnSharedPreferenceChangeListener(mListener);
  // listener example 监听器例子
  SharedPreferences.OnSharedPreferenceChangeListener mOnSharedPreferenceChangeListener
          = new SharedPreferences.OnSharedPreferenceChangeListener() {
      @Override
      public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
      }
  };

Editor

SharedPreferences.Editor是一个用来修改SharedPreferences对象值的接口。所有在Editor的修改会进行批处理,同时只有你调用了commit()或者apply()的时候才会复制到原来的SharedPreferences。

  • 用Editor的简单接口添加值
  • 用同步的commit()或速度更快异步的apply()来保存值。实际上在不同的线程使用commit()时会更安全。这是为什么我喜欢用commit()
  • 删除单个值用remove,删除所有值用clear()
  // get Editor object
  SharedPreferences.Editor editor = preferences.edit();
  // put values in editor
  editor.putBoolean("key", value);
  editor.put..("key", value);
  // remove single value by key
  editor.remove("key");
  // remove all values
  editor.clear();
  // commit your putted values to the SharedPreferences object synchronously
  // returns true if success 同步提交保存 成功返回true
  boolean result = editor.commit();
  // do the same as commit() but asynchronously (faster but not safely)
  // returns nothing 异步保存 不返回结果
  editor.apply();

性能和技巧

SharedPreferences是一个单例对象所以你可以轻易的获取它的多个引用,它只有在第一次调用getSharedPreferences的时候打开文件,只为它创建一个引用。(ps:真啰嗦,其实就是只实例化一次,后面调用会越来越快,看下面的例子)

  // There are 1000 String values in preferences
  SharedPreferences first = context.getSharedPreferences("com.example.app", Context.MODE_PRIVATE);
  // call time = 4 milliseconds第一次读取文件花了4毫秒
  SharedPreferences second = context.getSharedPreferences("com.example.app", Context.MODE_PRIVATE);
  // call time = 0 milliseconds第二次0
  SharedPreferences third = context.getSharedPreferences("com.example.app", Context.MODE_PRIVATE);
  // call time = 0 milliseconds第三次0

因为是单例对象你可以随意更改它多个实例的内容不用担心他们的数据会不同

  first.edit().putInt("key",15).commit();
  int firstValue = first.getInt("key",0)); // firstValue is 15
  int secondValue = second.getInt("key",0)); // secondValue is also 15

当你第一次调用get方法时,它会通过key解析获取到value然后会把它加到map中,第二次调用get会直接从map拿出,不用解析。

  first.getString("key", null)
  // call time = 147 milliseconds 第一次拿需要解析比较慢,然后会放到map中
  first.getString("key", null)
  // call time = 0 milliseconds 第二次直接从map中拿 ,不用解析 很快
  second.getString("key", null)
  // call time = 0 milliseconds 和第二次一样
  third.getString("key", null)
  // call time = 0 milliseconds

记住越大的Preference对象它的get,commit,apply,remove和clear等操作时间越长。所以推荐把你的数据分割成不同的小对象。

你的Preference不会在你的app更新后移除,所以有时候你需要创建一个迁移方案。例如你的app需要在启动的时候解析本地的JSON,只有在第一次启动执行然后保存boolean的标识wasLocalDataLoaded,一段时间后你更新了JSON发布了一个新版本,用户会更新app但是他们不会加载新的JSON因为他们在第一个版本已经做了。

  public class MigrationManager {
      private final static String KEY_PREFERENCES_VERSION = "key_preferences_version";
      private final static int PREFERENCES_VERSION = 2;
      public static void migrate(Context context) {
          SharedPreferences preferences = context.getSharedPreferences("pref", Context.MODE_PRIVATE);
          checkPreferences(preferences);
      }
      private static void checkPreferences(SharedPreferences thePreferences) {
          final double oldVersion = thePreferences.getInt(KEY_PREFERENCES_VERSION, 1);
          if (oldVersion < PREFERENCES_VERSION) {
              final SharedPreferences.Editor edit = thePreferences.edit();
              edit.clear();
              edit.putInt(KEY_PREFERENCES_VERSION, currentVersion);
              edit.commit();
          }
      }
  }

SharedPreferences保存在app的data文件夹下xml文件里面

// yours preferences 我们自己创建的
  /data/data/YOUR_PACKAGE_NAME/shared_prefs/YOUR_PREFS_NAME.xml
  // default preferences 默认
  /data/data/YOUR_PACKAGE_NAME/shared_prefs/YOUR_PACKAGE_NAME_preferences.xml

示例代码

    public class PreferencesManager {
        private static final String PREF_NAME = "com.example.app.PREF_NAME";
        private static final String KEY_VALUE = "com.example.app.KEY_VALUE";
        private static PreferencesManager sInstance;
        private final SharedPreferences mPref;
        private PreferencesManager(Context context) {
            mPref = context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE);
        }
        public static synchronized void initializeInstance(Context context) {
            if (sInstance == null) {
                sInstance = new PreferencesManager(context);
            }
        }
        public static synchronized PreferencesManager getInstance() {
            if (sInstance == null) {
                throw new IllegalStateException(PreferencesManager.class.getSimpleName() +
                        " is not initialized, call initializeInstance(..) method first.");
            }
            return sInstance;
        }
        public void setValue(long value) {
            mPref.edit()
                    .putLong(KEY_VALUE, value)
                    .commit();
        }
        public long getValue() {
            return mPref.getLong(KEY_VALUE, 0);
        }
        public void remove(String key) {
            mPref.edit()
                    .remove(key)
                    .commit();
        }
        public boolean clear() {
            return mPref.edit()
                    .clear()
                    .commit();
        }
    }

到此这篇关于Android SharedPreferences数据存储详解的文章就介绍到这了,更多相关Android SharedPreferences内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Android数据存储几种方式讲解

    目录 一.文件存储 1.写入文件步骤 2.读取文件步骤 3.实现存储和读取用户名和密码实例 二.SharedPreferences存储 三.SQLite数据库存储 四.ContentProvider存储 五.网络存储 一.文件存储 特点:openFileInput()和openFileOutput()读取设备上的文件. 优点:适用于存储大量的数据,可以存储图片.视频.文本等数据. 缺点:如果采用内部存储的方式,存储过量的数据可能会导致内存的不足:如果采用外部sdcard存储的方式,删除或者卸载应

  • Android本地数据存储Room实践和优化技巧

    目录 导入依赖 关键注解说明 一.使用步骤 二.类型转换器 三.结合RxJava Room在SQLite基础上做了ORM封装,使用起来类似JPA,不需要写太多的sql. 导入依赖 //roomdef room_version="2.4.2"implementation "androidx.room:room-runtime:$room_version"annotationProcessor "androidx.room:room-compiler:$roo

  • Android SharedPreference存储文件三步走

    目录 SharedPreference 概念与权限 存储数据 获取数据 简单存储案例 设置存取按钮 主代码 SharedPreference 他的使用方法非常简单,不夸张的说,仅需要一个 getSharedPreferences 就可以完成大部分操作 概念与权限 SharedPreference 存储文件的位置在:data/data/你的工程包名/shared_prefs getSharedPreferences 的第二个参数需要传入一个操作模式,目前仅剩下 MODE_PRIVATE 这一个可选

  • Android内部存储与外部存储的示例讲解

    目录 什么是内部存储和外部存储 内部存储与外部存储的代码示例 什么是内部存储和外部存储 1.内部存储与外部存储的存储介质: 内部存储的介质:RAM(内存) + 内部ROM 外部存储的介质:外部ROM + SDCard(TS卡等等). 2.内部存储与外部存储的存储特点: 一般来说,以/data开头的是内部存储.且内部存储不需要任何权限. 例如: /data/data/< applicationId >/shared_prefs /data/data/< applicationId >

  • Android中的存储详解

    目录 1.存储在App内部 2.SD卡外部存储 3.SharedPreferences存储 4.使用SQLite数据库存储 4.1 自己完成一个BaseDao类 4.2 使用Google写的API处理 4.3 事务使用 总结 1.存储在App内部 最简单的一种.在尝试过程中发现,手机中很多文件夹都没有权限读写.我们可以将我们需要写的文件存放到App中的files文件夹中,当然我们有权限在整个App中读写文件 可以通过API获取一个file对象,这里的this就是MainActivity类 //

  • Android json数据解析详解及实例代码

     Android json数据解析详解 移动开发经常要与服务器数据交互,也常使用json数据格式,那就说说Android json解析. 1.最简单json格式解析如下: //解析json ry { JSONTokener jsonParser = new JSONTokener(strResult); JSONObject jsonObj = (JSONObject) jsonParser.nextValue(); String strsportsTitle = jsonObj.getStri

  • IOS 数据存储详解及实例代码

    iOS应用数据存储的常用方式 XML属性列表(plist)归档 Preference(偏好设置) NSKeyedArchiver归档(NSCoding) SQLite3 Core Data 1. XML属性列表(plist)归档 每个iOS应用都有自己的应用沙盒(应用沙盒就是文件系统目录),与其他文件系统隔离.应用必须待在自己的沙盒里,其他应用不能访问该沙盒. 应用沙盒结构分析: 应用程序包:包含了所有的资源文件和可执行文件 Documents:保存应用运行时生成的需要持久化的数据,iTunes

  • java8中NIO缓冲区(Buffer)的数据存储详解

    java8新特性NIO缓冲区(Buffer)的数据存储. ByteBuffer,CharBuffer,ShortBuffer,IntBuffer,LongBuffer,FloatBuffer, DoubleBuffer. 1.缓冲区在java nio中负责数据的存储.缓冲区就是数组.用于存储不同数据类型的数据.根据数据类型不同(boolean除外),提供了相应类型的缓冲区. ByteBuffer,CharBuffer,ShortBuffer,IntBuffer,LongBuffer,FloatB

  • C语言数据存储详解

    目录 一.数据类型 二.整型在内存中的存储 1.原码.反码.补码 大小端介绍 三.浮点型在内存中的存储 1.举一个浮点数存储的例子: 2.浮点数存储规则: 总结 一.数据类型 char:字符数字类型.有无符号取决于编译器,大部分编译器有符号(signed char) 而short.int.long都是有符号的. unsigned char c1=255;内存中存放二进制的补码:11111111 都是有效位,没有符号位 char c2=255;结果为-1 同理可推出short.int等 二.整型在

  • C语言编程数据在内存中的存储详解

    目录 变量在计算机中有三种表示方式,原码反码,补码 原码 反码 补码 总结一下 浮点数在内存的储存 C语言中,有几种基本内置类型. int unsigned int signed int char unsigned char signed char long unsigned long signed long float double 在内存中创建变量,会在内存中开辟空间,并为其赋值. int a=10; 在计算机中,所有数据都是以二进制的形式存储在内存中. 变量在计算机中有三种表示方式,原码反

  • Android实现MVVM架构数据刷新详解流程

    目录 效果图 示例结构图 代码解析 导入dataBinding 实体类 xml视图 VM 绑定视图与数据层 效果图 示例结构图 代码解析 导入dataBinding dataBinding{ enabled = true } 实体类 继承BaseObservable public class Sensor extends BaseObservable 为字段添加@Bindable @Bindable public String getTmpValue() { return tmpValue; }

  • C语言数据的存储详解

    目录 数据类型的介绍 整形 浮点型 构造类型 指针类型 void空类型 整数在内存中的存储 原反补的介绍 大小端的介绍 面试例题 练习 浮点数在内存中的存储 存储规则讲解 举例 IEEE754的特别规定 案例 float用%d打印的特例讲解 数据类型的介绍 数据类型存在的意义 为变量开辟的空间大小(大小决定了使用范围) 取数据的时候按照什么格式取出(先看大小端,在看数据类型(用来解析二进制数据的方式)) 整形 char unsigned char signed char short unsign

  • Android中PreferenceActivity使用详解

    目录 一,Preference介绍 二,PreferencesActivity介绍 三,PreferenceActivity的使用 四,PreferenceActivity分别和ListFragment,PreferenceFragment组合使用 五,Preference数据获取 总结 一,Preference介绍 Android提供的preference以键值对的方式来处理这种情况:自动保存设置的数据,并立时生效,而这种使用android sharedpreferences方式进行保存的,不

  • Android 美食大转盘详解流程

    目录 效果视频 前言 美食大转盘 初始化SurfaceView 测量 绘制 绘制盘块 开始旋转转盘 停止旋转转盘 自定义转盘等份 控件引用 沉浸式体验 效果图 Reveal Animator 效果视频 自定义转盘代码 XML布局代码 Activity代码 代码下载地址 效果视频 前言 你还在为明天吃什么而烦恼嘛 美食大赏帮你解决选择困难症 帮你做出最佳的选择 做吃货,我们是认真的 美食大转盘 本示例使用SurfaceView绘制而成,接下来逐步分析, 文末会贴出全部代码``文末会贴出全部代码``

随机推荐