应用专属文件与应用偏好设置(SharedPreferences)


1. 概述 (Overview)

在 开发中,持久化存储是必不可少的功能。Android 提供了多种数据存储方式,其中 应用专属文件应用偏好设置(SharedPreferences) 是两种最常用、最基础的轻量级存储方案。

  • 应用专属文件 (App-Specific Files):用于存储应用私有的、结构化的或非结构化的文件数据(如文本、图片、JSON 等)。这些文件只能被创建它们的应用访问,当应用被卸载时,文件也会被自动删除。
  • 应用偏好设置 (SharedPreferences):用于存储简单的键值对(Key-Value)数据,通常用于保存用户的配置选项、登录状态、开关设置等。它以 XML 文件的形式存储在应用的私有目录中。

这两种方式都遵循"沙盒"安全模型,确保了应用数据的私密性和安全性。


2. 应用专属文件 (App-Specific Files)

Android 将应用的文件存储分为两类:内部存储(Internal Storage)外部存储(External Storage) 。对于大多数场景,尤其是需要保证隐私的数据,应优先使用内部存储

2.1 内部存储 (Internal Storage)

内部存储位于 /data/data/<package_name>/files/ 目录下,是应用私有的,其他应用无法直接访问。

2.1.1 获取内部存储路径
java 复制代码
// Java - 在 Activity 或 Context 中
File file = new File(getFilesDir(), "example.txt");
// 或者直接获取输出流
FileOutputStream fos = openFileOutput("example.txt", Context.MODE_PRIVATE);
  • getFilesDir(): 返回一个 File 对象,指向应用的内部文件目录。
  • openFileOutput(String name, int mode): 直接打开一个文件的输出流进行写入。
2.1.2 写入文件
java 复制代码
// Java
try {
    FileOutputStream fos = openFileOutput("config.json", Context.MODE_PRIVATE);
    fos.write("{\"theme\":\"dark\"}".getBytes());
    fos.close();
} catch (IOException e) {
    e.printStackTrace();
}
2.1.3 读取文件
java 复制代码
// Java
try {
    FileInputStream fis = openFileInput("config.json");
    StringBuilder content = new StringBuilder();
    int ch;
    while ((ch = fis.read()) != -1) {
        content.append((char) ch);
    }
    fis.close();
    String jsonContent = content.toString();
} catch (IOException e) {
    e.printStackTrace();
}

注意 : Context.MODE_PRIVATE 是唯一可用的模式,确保文件是私有的。

2.2 外部存储 (External Storage)

外部存储(如 SD 卡)可供所有应用和用户访问。从 Android 10 (API level 29) 开始,引入了分区存储(Scoped Storage) ,限制了应用对外部存储的访问范围。对于应用专属的外部文件,应使用 getExternalFilesDir()

java 复制代码
// Java - 获取应用专属的外部文件目录
File externalFile = new File(getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS), "report.pdf");
// 这个文件位于 /storage/emulated/0/Android/data/<package_name>/files/Documents/

优点: 即使应用被卸载,这些文件也不会被自动删除(除非用户手动清理),且不会占用内部存储空间。


3. 应用偏好设置 (SharedPreferences)

SharedPreferences 是一种轻量级的存储机制,专门用于存储简单的配置数据。

3.1 获取 SharedPreferences 实例
java 复制代码
// Java
// 方法一:使用应用默认的 SharedPreferences 文件
SharedPreferences prefs = getPreferences(Context.MODE_PRIVATE);

// 方法二:指定一个自定义的文件名(推荐)
SharedPreferences prefs = getSharedPreferences("MyAppPrefs", Context.MODE_PRIVATE);
3.2 写入数据 (Editor)

所有写入操作都必须通过 SharedPreferences.Editor 对象完成,并调用 apply()commit()

java 复制代码
// Java
SharedPreferences prefs = getSharedPreferences("MyAppPrefs", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = prefs.edit();

// 存储不同类型的数据
editor.putString("username", "john_doe");
editor.putInt("login_count", 5);
editor.putBoolean("is_dark_mode", true);
editor.putFloat("font_size", 14.0f);

// 提交更改
editor.apply(); // 异步提交,推荐
// editor.commit(); // 同步提交,会阻塞线程,不推荐
3.3 读取数据
java 复制代码
// Java
SharedPreferences prefs = getSharedPreferences("MyAppPrefs", Context.MODE_PRIVATE);

String username = prefs.getString("username", "default_user"); // 第二个参数是默认值
int loginCount = prefs.getInt("login_count", 0);
boolean isDarkMode = prefs.getBoolean("is_dark_mode", false);
float fontSize = prefs.getFloat("font_size", 12.0f);
3.4 移除和清空数据
java 复制代码
// Java
SharedPreferences.Editor editor = prefs.edit();

// 移除单个键
editor.remove("username");

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

editor.apply();

4. 使用场景对比
特性 应用专属文件 SharedPreferences
数据类型 任意格式(文本、二进制、JSON、图片等) 仅限基本数据类型(String, int, boolean, float, long, Set)
数据结构 无结构或自定义结构 键值对(Key-Value)
性能 适合存储大量或复杂数据 适合存储少量、简单的配置数据
使用复杂度 需要手动处理文件 I/O API 简单,开箱即用
典型用途 缓存图片、保存日志、存储 JSON 配置文件 保存用户设置、登录令牌、主题偏好、功能开关

5. 最佳实践与注意事项
  1. 优先使用内部存储 : 对于敏感或私有数据,务必使用内部存储 (getFilesDir()),以确保数据安全。
  2. 不要滥用 SharedPreferences: 它不是数据库,不适合存储大量数据或复杂对象。如果需要存储复杂数据,请考虑使用 Room 数据库。
  3. 使用 apply() 而非 commit() : apply() 是异步的,不会阻塞主线程,性能更好。只有在极少数需要立即确认写入结果的场景才使用 commit()
  4. 提供合理的默认值 : 在读取 SharedPreferences 时,始终提供一个有意义的默认值,以防键不存在。
  5. 文件命名规范 : 为文件和 SharedPreferences 文件使用清晰、一致的命名,便于维护。
  6. 及时清理无用文件: 对于缓存文件或临时文件,应在不再需要时主动删除,避免占用用户存储空间。
  7. 处理外部存储权限 : 如果必须访问共享的外部存储(非应用专属目录),需要在 Android 6.0+ 上动态申请 READ_EXTERNAL_STORAGE / WRITE_EXTERNAL_STORAGE 权限,并在 Android 10+ 上适配分区存储。

6. 结论

应用专属文件和 SharedPreferences 是 Android 开发中最基础、最常用的两种数据持久化方式。

  • 当你需要存储结构化的配置信息或用户的简单偏好 时,SharedPreferences 是最佳选择,它简单、高效且易于使用。
  • 当你需要存储任意格式的文件数据 (如文本、图片、JSON 对象等)时,应使用应用专属文件,并根据数据的隐私性和生命周期选择内部或外部存储。

正确理解和使用这两种机制,是构建健壮、可靠 Android 应用的基础。

相关推荐
普通网友21 小时前
Android Jetpack 架构组件最佳实践之“网抑云”APP
android·架构·android jetpack
普通网友21 小时前
原创_Android Jetpack Compose 最全上手指南
android·android jetpack
FDoubleman21 小时前
Android Jetpack之Compose入门(一)
android·android jetpack
普通网友21 小时前
Android Jetpack从入门到精通,干货满满
android·android jetpack
子云心21 小时前
Android Jetpack 系列(七)App Startup 启动优化
android·android jetpack·jetpack·initializer·startup·appstartup
嫩嫩的猿21 小时前
android jetpack compose Model对象更新变量 UI不更新、不刷新问题
android·ui·android jetpack
普通网友21 小时前
Android Jetpack 之 LifeCycle 组件_android 自定义view lifecycle
android·gitee·android jetpack
_codemonster1 天前
数据库字符集编码问题
android·数据库·oracle
Pika1 天前
深入浅出Compose HitTest 机制
android·android jetpack