上一篇
安卓开发之数据存储
- 行业动态
- 2025-04-22
- 2
安卓数据存储方式详解
SharedPreferences(轻量级键值存储)
适用场景:存储少量简单配置项(如用户偏好设置、登录状态等)。
特点:
- 以键值对形式存储(支持
String
、int
、boolean
等基本类型)。 - 数据持久化,默认存储在应用私有目录。
- 操作简单,无需手动管理文件或数据库。
使用方法:
// 获取实例(私有模式) SharedPreferences sp = getSharedPreferences("config", MODE_PRIVATE); // 写入数据 sp.edit() .putString("username", "John") .putBoolean("isLoggedIn", true) .apply(); // 异步提交 // 读取数据 String username = sp.getString("username", "default"); boolean isLoggedIn = sp.getBoolean("isLoggedIn", false);
优点:
- 简单易用,适合少量配置数据。
- 自动处理数据序列化和反序列化。
缺点:
- 仅支持简单数据类型,无法存储复杂结构。
- 不适合大量数据或高频读写场景。
文件存储(File)
适用场景:存储文本文件(如日志)、二进制文件(如图片缓存)、配置文件等。
特点:
- 分为内部存储(应用私有,无需权限)和外部存储(需申请权限,Android 10+需特殊处理)。
- 支持
InputStream
/OutputStream
操作,可读写任意格式文件。
内部存储示例:
// 写入文件 File file = new File(getFilesDir(), "config.txt"); try (FileOutputStream fos = new FileOutputStream(file)) { fos.write("key=value".getBytes()); } // 读取文件 try (BufferedReader reader = new BufferedReader(new FileReader(file))) { String line = reader.readLine(); }
外部存储示例(Android 10+):
// 使用MediaStore API保存图片(替代直接写入外部存储) ContentValues values = new ContentValues(); values.put(MediaStore.Images.Media.DISPLAY_NAME, "image.jpg"); values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg"); Uri uri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values); try (OutputStream os = getContentResolver().openOutputStream(uri)) { // 写入图片数据 }
优点:
- 灵活支持多种文件格式。
- 内部存储数据安全,外部存储可共享。
缺点:
- 需处理文件路径、权限和兼容性(尤其是Android 10+的沙盒限制)。
- 不适合结构化查询。
SQLite数据库(结构化存储)
适用场景:存储复杂关系型数据(如用户信息、订单列表等)。
特点:
- 轻量级嵌入式数据库,支持SQL语法。
- 数据持久化,需手动管理表结构和增删改查操作。
使用方法:
// 通过SQLiteOpenHelper创建数据库 public class DBHelper extends SQLiteOpenHelper { public DBHelper(Context context) { super(context, "app.db", null, 1); } @Override public void onCreate(SQLiteDatabase db) { db.execSQL("CREATE TABLE user (id INTEGER PRIMARY KEY, name TEXT)"); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { // 更新表结构逻辑 } } // 增删改查操作 SQLiteDatabase db = new DBHelper(context).getWritableDatabase(); db.execSQL("INSERT INTO user (name) VALUES (?)", new Object[]{"Alice"}); Cursor cursor = db.rawQuery("SELECT FROM user", null);
优点:
- 支持复杂查询和事务管理。
- 数据结构化,适合大量数据存储。
缺点:
- 需手动处理数据库操作和线程安全。
- 代码复杂度较高(推荐使用
Room
组件简化)。
ContentProvider(跨应用数据共享)
适用场景:对外提供数据访问接口(如分享文件、读取联系人等)。
特点:
- 基于
URI
抽象数据,支持跨应用权限控制。 - 通过
ContentResolver
实现统一数据操作。
示例:访问联系人数据
// 查询联系人 Uri uri = ContactsContract.Contacts.CONTENT_URI; Cursor cursor = getContentResolver().query(uri, null, null, null, null); while (cursor.moveToNext()) { String name = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)); }
优点:
- 标准化数据共享机制,安全性高。
- 支持复杂权限管理(如
READ_CONTACTS
)。
缺点:
- 实现复杂,需处理
URI
匹配和数据封装。 - 性能依赖具体实现。
数据存储方式对比表
存储类型 | 数据格式 | 适用场景 | 操作复杂度 | 持久性 | 跨应用共享 | 安全性 |
---|---|---|---|---|---|---|
SharedPreferences | 键值对(基本类型) | 简单配置项 | 低 | 是 | 否 | 一般 |
文件存储 | 文本/二进制文件 | 配置文件、缓存文件 | 中 | 是(内部)/否(外部) | 外部存储可共享 | 依赖存储位置 |
SQLite数据库 | 结构化表数据 | 复杂业务数据 | 高 | 是 | 否(需ContentProvider) | 高 |
ContentProvider | 自定义数据模型 | 跨应用数据共享 | 高 | 是 | 是 | 高 |
相关问题与解答
问题1:如何选择安卓数据存储方式?
解答:
- 简单配置:使用
SharedPreferences
(如夜间模式开关)。 - 文件类数据:使用文件存储(如图片缓存、日志文件)。
- 结构化数据:使用
SQLite
(如用户信息、订单列表)。 - 跨应用共享:通过
ContentProvider
暴露数据(如自定义文件格式)。 - 云同步需求:结合
Room
+LiveData
本地存储,配合网络请求同步。
问题2:如何保证安卓数据存储的安全性?
解答:
- 权限控制:
- 敏感数据存储在内部存储或加密文件中。
- 对外共享数据时,在
AndroidManifest
中限制ContentProvider
的exported
属性。
- 数据加密:
- 使用
EncryptedSharedPreferences
(AndroidX库)加密偏好设置。 - 对文件和数据库启用AES加密(如
SQLCipher
库)。
- 使用
- 网络安全:
网络传输时使用HTTPS,避免明文存储敏感信息(如密码需哈希+盐处理