Android-SharedPreferences详细使用

目录

  • SharedPreferences
    • 一、简介
    • 二、了解
      • 1 数据存储
      • 2 数据读取
      • 3 常用方法
        • 3.1 getSharedPreferences()
        • 3.2 edit()
        • 3.4 remove() 移除数据
        • 3.5 clear() 清空数据
        • 3.6 commit() 提交保存数据
    • 三、基本使用
      • 1 一个示例
    • 四、监听
    • 五、性能分析
    • 六、使用过程中的注意点
      • 1 获取 SharedPreferences 对象
      • 2 数据存放周期
      • 3 SharedPreferences不是强类型的
      • 4 value类型不一致导致的运行时异常
      • 5 需要执行commit的函数

SharedPreferences

Question: 1

SharedPreferences有没有现成安全机制 ???

如果有,如何做,通用做法??? 还是内部支持 ???

Question: 2

SharedPreferences在读写的操作上有什么优化建议、优化空间 ???

一、简介

一个轻量级的存储类,特别适合用于保存软件配置参数。

(是用xml文件存放数据,文件存放在/data/data//shared_prefs目录下)

有时候需要将少量简单类型数据保存在本地,例如用户的配置数据、用户的部分非强安全数据(如用户名、用户的头像等等)

有时候,也可以通过利用SharedPreferences来存储用户的用户名和密码,以此来达到用户打开APP时同步登录、记住密码一键登录的需求/效果。

这些需求存储的数据一般都比较简单

SharedPreferences可以保存的数据类型有:int、boolean、float、long、String、StringSet。

tips:对于Java或kotlin的对象类型数据(例如用来存储用户名、密码等用户信息的User类),则可以将其进行序列化为字符串进行存储

二、了解

1 数据存储

保存数据一般分为四个步骤:

  1. 使用Activity类的getSharedPreferences方法获得SharedPreferences对象;
  2. 使用SharedPreferences接口的edit获得SharedPreferences.Editor对象;
  3. 通过SharedPreferences.Editor接口的putXXX方法写入key-value对;
  4. 通过过SharedPreferences.Editor接口的commit方法保存key-value对。

2 数据读取

读取数据一般分为两个步骤:

  1. 使用Activity类的getSharedPreferences方法获得SharedPreferences对象;
  2. 通过SharedPreferences对象的getXXX方法获取数据;

3 常用方法

3.1 getSharedPreferences()
public abstract SharedPreferences getSharedPreferences (String name, int mode)

作用:用于获取SharedPreferences对象
(根据name查找SharedPreferences,若已经存在则获取,若不存在则创建一个新的)

参数
name:命名
mode:模式,包括
MODE_PRIVATE(只能被自己的应用程序访问)
MODE_WORLD_READABLE(除了自己访问外还可以被其它应该程序读取)
MODE_WORLD_WRITEABLE(除了自己访问外还可以被其它应该程序读取和写入)

值得关注的是,若该Activity只需要创建一个SharedPreferences对象的时候,可以使用getPreferences方法,不需要为SharedPreferences对象命名,只要传入参数mode即可

public SharedPreferences getPreferences (int mode)
3.2 edit()
abstract SharedPreferences.Editor edit()

作用:用于获取SharedPreferences的Editor对象

3.3 putXxx()

//写入boolean类型的数据
abstract SharedPreferences.Editor   putBoolean(String key, boolean value)
//写入float类型的数据
abstract SharedPreferences.Editor   putFloat(String key, float value)
//写入int类型的数据
abstract SharedPreferences.Editor   putInt(String key, int value)
//写入long类型的数据
abstract SharedPreferences.Editor   putLong(String key, long value)
//写入String类型的数据
abstract SharedPreferences.Editor   putString(String key, String value)
//写入Set类型的数据
abstract SharedPreferences.Editor   putStringSet(String key, Set<String> values)

作用:用于完成数据的写入

注意,是通过SharedPreferences的Editor对象完成调用

参数
key:指定数据对应的key
value:指定的值

3.4 remove() 移除数据

作用:用于移除指定key的数据

abstract SharedPreferences.Editor remove(String key)

参数
key:指定数据的key

(TODO: Key不存在时的处理方法是怎么样的)

3.5 clear() 清空数据

作用:清空数据(谨慎操作)

3.6 commit() 提交保存数据

3.7 getXxx() 读取数据

//读取所有数据
abstract Map<String, ?> getAll()
//读取的数据为boolean类型
abstract boolean    getBoolean(String key, boolean defValue)
//读取的数据为float类型
abstract float  getFloat(String key, float defValue)
//读取的数据为int类型
abstract int    getInt(String key, int defValue)
//读取的数据为long类型
abstract long   getLong(String key, long defValue)
//读取的数据为String类型
abstract String getString(String key, String defValue)
//读取的数据为Set类型
abstract Set<String>    getStringSet(String key, Set<String> defValues)

参数
key:指定数据的key
defValue:当读取不到指定的数据时,使用的默认值defValue

三、基本使用

1 一个示例

    /**
     * 保存用户信息
     */
    private void saveUserInfo(){
        SharedPreferences userInfo = getSharedPreferences(PREFS_NAME, MODE_PRIVATE);
        SharedPreferences.Editor editor = userInfo.edit();//获取Editor
        //得到Editor后,写入需要保存的数据
        editor.putString("username", "一只猫的涵养");
        editor.putInt("age", 20);
        editor.commit();//提交修改
        Log.i(TAG, "保存用户信息成功");
    }
    /**
     * 读取用户信息
     */
    private void getUserInfo(){
        SharedPreferences userInfo = getSharedPreferences(PREFS_NAME, MODE_PRIVATE);
        String username = userInfo.getString("username", null);//读取username
        int age = userInfo.getInt("age", 0);//读取age
        Log.i(TAG, "读取用户信息");
        Log.i(TAG, "username:" + username + ", age:" + age);
    }
    /**
     * 移除年龄信数据
     */
    private void removeUserInfo(){
        SharedPreferences userInfo = getSharedPreferences(PREFS_NAME, MODE_PRIVATE);
        SharedPreferences.Editor editor = userInfo.edit();//获取Editor
        editor.remove("age");
        editor.commit();
        Log.i(TAG, "移除年龄数据");
    }

    /**
     * 清空数据
     */
    private void clearUserInfo(){
        SharedPreferences userInfo = getSharedPreferences(PREFS_NAME, MODE_PRIVATE);
        SharedPreferences.Editor editor = userInfo.edit();//获取Editor
        editor.clear();
        editor.commit();
        Log.i(TAG, "清空数据");
    }

四、监听

SharedPreferences被编辑时的监听

SharedPreferences.OnSharedPreferenceChangeListener changeListener = new 			OnSharedPreferenceChangeListener() {
    @Override
    public void onSharedPreferenceChanged(SharedPreferences preferences, String key) {
        //preferences被 编辑的SharedPreferences实例
        //该SharedPreferences中被编辑的条目所对应的key
    }
};
//userInfo注册监听事件
userInfo.registerOnSharedPreferenceChangeListener(changeListener);
//userInfo注销监听事件
userInfo.unregisterOnSharedPreferenceChangeListener(changeListener);

五、性能分析

ShredPreferences是单例对象,第一次打开后,之后获取都无需创建,速度很快。

当第一次获取数据后,数据会被加载到一个缓存的Map中,之后的读取都会非常快。

当由于是 XML <—> Map 的存储方式,所以,数据越大,操作越慢,get、commit、apply、remove、clear都会受影响,所以尽量把数据按功能拆分成若干份(即对应3.1中的api,传入name进行区分)。

Question:

  1. 什么时候销毁MAP?程序退出还是?
  2. 一个name SharedPreferences 对应一个Map ,还是系统统一维护一个Map ?

六、使用过程中的注意点

1 获取 SharedPreferences 对象

这些方法、常量在Activity中可以直接调用

getSharedPreferences (String name, int mode)
getPreferences (int mode) 
MODE_PRIVATE

而如果不是在Activity中,例如是在Service或者其他工具类中,则是通过Context对象来进行获取:

context.getSharedPreferences (String name, int mode)
context.getPreferences (int mode)
Conetxt.MODE_PRIVATE 

2 数据存放周期

保存的SharedPreferences数据将一直存在,除非被覆盖、移除、清空或文件被删除。

SharedPreferences保存的数据会随着应用的卸载而被删除

注意,覆盖安装(例如版本更新)并不会删除或清空SharedPreferences文件

3 SharedPreferences不是强类型的

(这里的强类型是个人定义.)

即,在SharedPreferences中存储的value不限定类型,与最新一次的覆盖写入有关

例如,如下两个代码都会造成key为age的数据被覆盖写入而发生更新变化

case 1:

editor.putInt("age", 20);
//覆盖key为age的数据,得到的结果:age = 32
editor.putInt("age", 32);

// 这时候通过
sharedPreferences.getInt("age", 0)  // 获取得到的值为:

case 2:

editor.putString("age", "20");
//覆盖key为age的数据,得到的结果:age = 32 (int类型)
editor.putInt("age", 32);

// 这时候通过
sharedPreferences.getInt("age", 0)  // 获取得到的值为:

sharedPreferences.getString("age", "0")  // 获取得到的值为:

4 value类型不一致导致的运行时异常

所读取的key存在,但是读取时指定的类型不对应,则会产生运行时异常。

editor.putInt("age", 32);//保存为int类型
String age = userInfo.getString("age", "null");//读取时为String类型,出现异常

5 需要执行commit的函数

// putXxx()
editor.putInt("age", 20);//写入操作
editor.remove("age");   //移除操作
editor.clear();     //清空操作
editor.commit();//记得commit

你可能感兴趣的:(Android,android)