安卓系统提供多种存储方式,不同场景适用不同方案:
存储类型 | 读写权限 | 数据持久性 | 适用场景 |
---|---|---|---|
内部存储(Internal) | 应用私有,无需声明权限 | 永久 | 敏感配置、用户生成文件 |
外部存储(External) | 需动态申请权限 | 永久/可清除 | 媒体文件、缓存数据 |
SQLite数据库 | 应用私有 | 永久 | 结构化数据存储 |
SharedPreferences | 应用私有 | 永久 | 轻量级键值对配置 |
网络存储 | 依赖网络权限 | 可变 | 云同步、大文件存储 |
内部存储操作
// 写入文件 File file = new File(context.getFilesDir(), "config.txt"); try (FileOutputStream fos = new FileOutputStream(file)) { fos.write("app_config".getBytes()); } // 读取文件 try (FileInputStream fis = new FileInputStream(file)) { byte[] buffer = new byte[fis.available()]; fis.read(buffer); String content = new String(buffer); }
外部存储适配(Android 10+)
// 获取应用专属外部存储目录 File externalDir = context.getExternalFilesDir(Environment.DIRECTORY_PICTURES); if (externalDir != null) { File imageFile = new File(externalDir, "app_image.jpg"); // 执行文件操作... } // 传统公有目录访问(需处理分区存储限制) File publicDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
SQLite基础使用
// 创建数据库助手类 public class DBHelper extends SQLiteOpenHelper { private static final String DATABASE_NAME = "app.db"; @Override public void onCreate(SQLiteDatabase db) { db.execSQL("CREATE TABLE users(id INTEGER PRIMARY KEY,name TEXT)"); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { db.execSQL("DROP TABLE IF EXISTS users"); onCreate(db); } }
Room持久化库优势
Android版本 | 外部存储权限 | 作用范围 |
---|---|---|
Android 9- | WRITE_EXTERNAL_STORAGE | 整个外部存储 |
Android 10+ | MANAGE_EXTERNAL_STORAGE | 仅限应用专属目录 |
Android 11+ | MANAGE_EXTERNAL_STORAGE | 需用户手动授权跨应用访问 |
动态权限申请示例
// 检查并请求权限 if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_CODE); }
备份方式 | 实现方式 | 适用场景 |
---|---|---|
自动云端备份 | BackupAgent + Cloud服务 | 关键配置数据 |
手动文件备份 | 自定义导出逻辑 | 用户生成的文档/图片 |
数据库同步 | Room + LiveData/SyncAdapter | 结构化业务数据 |
Cipher
进行AES加密requestLegacyExternalStorage
属性StatFs statFs = new StatFs(Environment.getExternalStorageDirectory().getPath()); long availableSpace = statFs.getAvailableBlocksLong() statFs.getBlockSizeLong();
Q1:如何将现有应用迁移到Android 10+的Scoped Storage?
A:迁移步骤:
AndroidManifest.xml
添加属性: <application android:requestLegacyExternalStorage="true">
getExternalStorage
方法为getExternalFilesDir()
等Scoped APIMediaStore
API操作公有目录文件requestLegacyExternalStorage
属性Q2:如何选择SharedPreferences与SQLite数据库?
A:决策依据:
| 需求特征 | 推荐方案 | 原因 |
|————————-|——————-|———————————————————————-|
| 简单键值对存储 | SharedPreferences | 天然支持类型安全,API调用简单 |
| 结构化数据管理 | SQLite | 支持索引、事务、复杂查询,适合多表关联操作 |
| 频繁读写性能要求 | SharedPreferences | 底层使用内存缓存,读写速度更快 |
| 大数据量持久化 | SQLite | 可处理GB级数据,支持备份恢复机制 |