Android客户端本地存储的方式(SharedPreferences)

74 阅读3分钟

SharedPreferences 详解

概述

SharedPreferences 是 Android 提供的轻量级数据存储机制,用于保存应用的配置信息和用户偏好设置。它以键值对的形式将数据存储在 XML 文件中(类似前端中的localStorage)。

核心特点

  • 轻量级:适合存储少量简单数据
  • 持久化:数据在应用重启后依然存在
  • 线程安全:支持多线程访问
  • 键值对存储:以 key-value 形式组织数据

基本用法

1. 初始化 SharedPreferences

// 获取 SharedPreferences 实例
SharedPreferences sharedPreferences = getSharedPreferences("文件名", MODE_PRIVATE);

参数说明:

  • 文件名:XML文件名称,如 "MyPrefs" 会创建 MyPrefs.xml
  • MODE_PRIVATE:访问模式,只允许当前应用访问(推荐)

2. 保存数据

// 获取编辑器
SharedPreferences.Editor editor = sharedPreferences.edit();

// 只能保存六种类型的数据
editor.putString("username", "张三");
editor.putInt("age", 25);
editor.putBoolean("isLogin", true);
editor.putFloat("score", 98.5f);
editor.putLong("timestamp", System.currentTimeMillis());
Set<String> hobbies = new HashSet<>();
hobbies.add("游泳");
hobbies.add("跑步");
editor.putStringSet("hobbies", hobbies);

// 提交保存
editor.apply(); // 推荐:异步保存
// 或者
editor.commit(); // 同步保存,返回 boolean 结果

3. 读取数据

// 读取数据,提供默认值
String username = sharedPreferences.getString("username", "未知用户");
int age = sharedPreferences.getInt("age", 0);
boolean isLogin = sharedPreferences.getBoolean("isLogin", false);
float score = sharedPreferences.getFloat("score", 0.0f);
long timestamp = sharedPreferences.getLong("timestamp", 0L);

4. 删除数据

SharedPreferences.Editor editor = sharedPreferences.edit();

// 删除指定键
editor.remove("username");

// 清空所有数据
editor.clear();

// 提交删除操作
editor.apply();
每次修改(增加、删除)数据都需要多执行一次apply或者commit

支持的数据类型

方法数据类型示例
putString() / getString()String"Hello World"
putInt() / getInt()int123
putBoolean() / getBoolean()booleantrue / false
putFloat() / getFloat()float3.14f
putLong() / getLong()long123456789L
putStringSet() / getStringSet()Set{"item1", "item2"}

apply() vs commit() 对比

特性apply()commit()
执行方式异步同步
返回值voidboolean
性能更好较差
UI阻塞不会阻塞可能阻塞
推荐使用✅ 推荐❌ 不推荐
// 推荐写法
editor.putString("key", "value");
editor.apply();

// 不推荐写法(除非需要返回结果)
boolean success = editor.putString("key", "value").commit();

实际应用场景

1. 用户偏好设置

// 保存主题设置
editor.putString("theme", "dark");
editor.putBoolean("notifications_enabled", true);
editor.apply();

// 读取设置
String theme = prefs.getString("theme", "light");
boolean notificationsEnabled = prefs.getBoolean("notifications_enabled", true);

2. 登录状态管理

// 保存登录信息
editor.putBoolean("is_logged_in", true);
editor.putString("user_token", "abc123");
editor.putLong("login_time", System.currentTimeMillis());
editor.apply();

// 检查登录状态
boolean isLoggedIn = prefs.getBoolean("is_logged_in", false);

3. 应用配置

// 首次启动标记
editor.putBoolean("first_launch", false);
editor.putInt("app_version", BuildConfig.VERSION_CODE);
editor.apply();

// 检查是否首次启动
boolean isFirstLaunch = prefs.getBoolean("first_launch", true);

文件存储位置

SharedPreferences 文件存储在应用的私有目录:

/data/data/包名/shared_prefs/文件名.xml

例如:

/data/data/com.example.myapp/shared_prefs/MyPrefs.xml

XML 文件格式示例

<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<map>
    <string name="username">张三</string>
    <int name="age" value="25" />
    <boolean name="isLogin" value="true" />
    <float name="score" value="98.5" />
    <long name="timestamp" value="1234567890" />
</map>

使用范围和限制

✅ 适用场景

  • 用户偏好设置(主题、语言等)
  • 登录状态和用户信息
  • 应用配置参数
  • 简单的统计数据
  • 首次启动标记

❌ 不适用场景

  • 大量数据存储
  • 复杂的数据结构
  • 需要查询的数据
  • 敏感信息(密码等)
  • 频繁变化的数据

数据大小限制

  • 建议单个文件不超过 1MB
  • 适合存储少量配置数据
  • 大量数据应使用 SQLite 数据库

与其他存储方式对比

存储方式适用场景数据大小复杂度查询能力
SharedPreferences配置、偏好简单
SQLite结构化数据中等
文件存储任意数据中等
Room现代数据库简单

最佳实践

1. 合理命名

// 好的命名
SharedPreferences userPrefs = getSharedPreferences("UserPreferences", MODE_PRIVATE);
SharedPreferences appSettings = getSharedPreferences("AppSettings", MODE_PRIVATE);

// 避免通用名称
SharedPreferences prefs = getSharedPreferences("data", MODE_PRIVATE);

2. 使用常量管理键名

public class PrefsKeys {
    public static final String USER_NAME = "user_name";
    public static final String IS_LOGGED_IN = "is_logged_in";
    public static final String THEME = "theme";
}

// 使用常量
editor.putString(PrefsKeys.USER_NAME, username);
String userName = prefs.getString(PrefsKeys.USER_NAME, "");

3. 封装工具类

public class PrefsManager {
    private static final String PREF_NAME = "MyAppPrefs";
    private SharedPreferences prefs;
    private SharedPreferences.Editor editor;
    
    public PrefsManager(Context context) {
        prefs = context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE);
        editor = prefs.edit();
    }
    
    public void saveUserName(String userName) {
        editor.putString("user_name", userName);
        editor.apply();
    }
    
    public String getUserName() {
        return prefs.getString("user_name", "");
    }
}

注意事项

  1. 线程安全:SharedPreferences 是线程安全的,但 Editor 不是
  2. 内存占用:首次访问时会将整个文件加载到内存
  3. 性能考虑:避免在主线程进行大量读写操作
  4. 数据备份:SharedPreferences 会自动参与应用数据备份

Xiao Huang who wishes to get enough money