应用专属文件与应用偏好设置(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 应用的基础。

相关推荐
千里马学框架4 天前
一起学 Android 14:ShellTransition 屏幕旋转过程深度剖析
android·智能手机·性能优化·framework·性能·屏幕旋转·rotation
美狐美颜SDK开放平台4 天前
开发直播APP时如何接入视频美颜SDK?开发流程与注意事项
android·人工智能·计算机视觉·音视频·直播美颜sdk
AFinalStone4 天前
Android7 SystemUI源码解析(七)Keyguard锁屏模块深度解析
android·systemui
致远ccc4 天前
Google Play 上架前如何测试 App?多国家 Android 环境测试
android·app测试·googleplay·多国家应用测试
ttyyttemo4 天前
Kotlin 协程中的 Job 结构化并发与取消
android
sun0077004 天前
tbox 4g/5g切换,导致wan ip 改变,导致车机旧网络不可用。需要重启车机才行
android
其实防守也摸鱼5 天前
内网穿透与反向代理:原理、工具与实战指南
android·大数据·运维·安全·网络安全·自动化·渗透
AFinalStone5 天前
Android7 SystemUI 源码解析(四)NavigationBar 导航栏与 SystemBars
android·systemui
JMchen5 天前
属性动画原理与高级动画实现
android·kotlin·canvas
AFinalStone5 天前
Android7 SystemUI 源码解析(二)启动流程深度解析
android·systemui