Android 入门教程
存储概览
本教程共 100 篇 · 第 64 篇 · 更新于 2026-07-28 · 约 7 分钟阅读
AndroidAndroid 入门教程数据存储内部存储外部存储SharedPreferencesRoom
64. 存储概览
本节目标:了解 Android 提供的四种数据存储方案,知道每种方案的适用场景,能根据需求选对存储方式。
四种存储方案
Android 提供四种保存应用数据的方式:
| 方案 | 数据类型 | 需要权限 | 其他应用可访问 | 卸载时删除 |
|---|---|---|---|---|
| 应用专属存储 | 仅供本应用的文件 | 否 | 否 | 是 |
| 共享存储 | 媒体、文档等共享文件 | 部分需要 | 是 | 否 |
| 偏好设置 | 键值对 | 否 | 否 | 是 |
| 数据库 | 结构化数据 | 否 | 否 | 是 |
打个比方:应用专属存储像你的私人保险柜,只有你能开;共享存储像公共图书馆,大家都能看;偏好设置像你的笔记本,记点小配置;数据库像档案柜,存大量有条理的记录。
应用专属存储
存只有你的应用能访问的文件,比如缓存图片、下载的配置文件。分内部存储和外部存储两个位置。
// 内部存储:空间小但始终可用,卸载即删
val file = File(context.filesDir, "config.txt")
// 缓存目录:系统内存不足时可能清除
val cacheFile = File(context.cacheDir, "temp.cache")
// 外部存储:空间大,卸载即删,不需要权限
val extFile = File(context.getExternalFilesDir(null), "photo.jpg")
| 目录 | 方法 | 特点 |
|---|---|---|
| 内部文件 | filesDir | 始终可用,空间有限 |
| 内部缓存 | cacheDir | 系统可清理 |
| 外部文件 | getExternalFilesDir() | 空间大,不需权限 |
| 外部缓存 | getExternalCacheDir() | 系统可清理 |
Note
- Android 10+ 引入分区存储(Scoped Storage)后,外部存储的访问方式变了。但
getExternalFilesDir()拿到的是应用专属目录,不受分区存储限制,不需要任何权限。这是存应用文件的首选位置。
共享存储
存需要和其他应用共享的文件,比如拍的照片、下载的文档。通过 MediaStore API 或存储访问框架(SAF)访问。
// 通过 MediaStore 保存图片到公共相册
val resolver = context.contentResolver
val imageCollection = MediaStore.Images.Media.getContentUri(
MediaStore.VOLUME_EXTERNAL_PRIMARY
)
val values = ContentValues().apply {
put(MediaStore.Images.Media.DISPLAY_NAME, "photo.jpg")
put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg")
}
val uri = resolver.insert(imageCollection, values)
Warning
- 共享存储涉及分区存储和权限问题比较复杂。Android 13+ 把
READ_EXTERNAL_STORAGE拆成了READ_MEDIA_IMAGES、READ_MEDIA_VIDEO、READ_MEDIA_AUDIO三个细粒度权限。第 66 章会详细讲文件存储。
偏好设置
存简单的键值对配置,比如用户设置(主题颜色、是否开启通知)。
val sharedPref = context.getSharedPreferences("settings", Context.MODE_PRIVATE)
// 写
sharedPref.edit {
putString("theme", "dark")
putBoolean("notifications", true)
}
// 读
val theme = sharedPref.getString("theme", "light")
Note
- SharedPreferences 适合存少量简单数据(配置、标志位)。它同步读、异步写,不适合存大量数据或复杂结构。官方现在推荐用 DataStore 替代,第 65 章会详细讲。
数据库
存大量结构化数据,比如通讯录、聊天记录、商品列表。官方推荐用 Room 持久化库(基于 SQLite)。
// Room 的基本结构(第 67-68 章详细讲)
@Entity
data class User(
@PrimaryKey val id: Int,
val name: String,
val age: Int
)
@Dao
interface UserDao {
@Query("SELECT * FROM user")
fun getAll(): List<User>
@Insert
fun insert(user: User)
}
如何选择
| 需求 | 推荐方案 |
|---|---|
| 几个配置项(主题、开关) | SharedPreferences / DataStore |
| 应用私有文件(缓存、下载) | 应用专属存储 |
| 用户拍的照片、下载的文档 | 共享存储(MediaStore / SAF) |
| 大量结构化数据(列表、记录) | Room 数据库 |
| 跨应用共享数据 | ContentProvider + 数据库 |
选择思路:
- 数据量大吗? 小就用偏好设置,大就用数据库或文件。
- 数据有结构吗? 有结构(表格)用 Room,无结构(文件)用文件存储。
- 别的应用要访问吗? 要就放共享存储或 ContentProvider,不要就放专属存储。
- 是临时数据吗? 临时数据放缓存目录,系统会自动清理。
Tip
- 实际项目里,一个应用通常同时用多种存储方案:用户配置用 DataStore,缓存文件用专属存储目录,业务数据用 Room 数据库,用户生成的图片用 MediaStore。根据数据特点选方案,不要一种方案打天下。
存储位置与权限
内部存储(始终可用,私有)
├── /data/data/<包名>/files/ ← filesDir
├── /data/data/<包名>/cache/ ← cacheDir
└── /data/data/<包名>/shared_prefs/ ← SharedPreferences
外部存储(空间大,分区存储)
├── /sdcard/Android/data/<包名>/files/ ← getExternalFilesDir()
├── /sdcard/Android/data/<包名>/cache/ ← getExternalCacheDir()
└── /sdcard/Pictures/ 等 ← 共享存储,需 MediaStore API
Warning
- 别硬编码路径(如
/sdcard/...),不同设备路径不同。用filesDir、getExternalFilesDir()等方法获取,框架保证路径正确。
小结
四种存储方案各有定位:偏好设置存配置、专属存储存私有文件、共享存储存媒体文档、数据库存结构化数据。选择看数据量、结构、是否共享、是否临时。接下来三章分别深入 SharedPreferences、文件存储和 SQLite 数据库。