安卓开发 存储对象
- 行业动态
- 2025-04-22
- 4
安卓开发中存储对象的实现方式
在安卓开发中,存储对象数据需要根据数据类型、生命周期、性能需求等选择合适的存储方案,以下是常见的存储方式及其特点:
SharedPreferences(共享偏好)
适用场景:轻量级键值对存储,适合保存简单配置(如用户设置、登录状态)。
特点:
- 基于XML文件,本质是键值对(支持
String
、int
、boolean
等基本类型)。 - 自动持久化,无需手动提交。
- 不适合存储复杂对象或大量数据。
- 基于XML文件,本质是键值对(支持
存储对象的方式:
将对象转为JSON字符串或序列化后存储。
示例:
// 存储对象 User user = new User("John", 25); SharedPreferences sp = getSharedPreferences("user_prefs", MODE_PRIVATE); SharedPreferences.Editor editor = sp.edit(); editor.putString("user", new Gson().toJson(user)); // 需引入Gson库 editor.apply(); // 读取对象 String json = sp.getString("user", ""); User restoredUser = new Gson().fromJson(json, User.class);
文件存储(Internal/External Storage)
适用场景:存储文件(如图片、视频、配置文件)、复杂对象(需序列化)。
特点:
- 内部存储:仅限本应用访问,数据不会暴露给其他应用。
- 外部存储:可被用户或其他应用访问,需处理权限(如
READ_EXTERNAL_STORAGE
)。 - 适合存储二进制文件或文本文件。
存储对象的方式:
将对象序列化(如Java的
Serializable
或Parcelable
)后写入文件。示例(内部存储):
// 写入对象 File file = new File(getFilesDir(), "user.dat"); ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file)); oos.writeObject(user); // User类需实现Serializable oos.close(); // 读取对象 ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file)); User restoredUser = (User) ois.readObject(); ois.close();
SQLite数据库(通过Room封装)
适用场景:结构化数据存储,需支持增删改查、索引、事务等操作。
特点:
- 轻量级关系型数据库,适合复杂数据关联。
- 直接操作SQL语句较繁琐,推荐使用
Room
库简化。
存储对象的方式:
将对象映射为数据库表,通过DAO(Data Access Object)操作。
示例(Room):
// 定义实体 @Entity public class User { @PrimaryKey(autoGenerate = true) public int id; public String name; public int age; } // 定义DAO @Dao public interface UserDao { @Insert void insert(User user); @Query("SELECT FROM User WHERE id = :id") User getUserById(int id); } // 使用数据库 AppDatabase db = Room.databaseBuilder(context, AppDatabase.class, "app_db").build(); UserDao userDao = db.userDao(); userDao.insert(user); // 存储对象 User restoredUser = userDao.getUserById(1); // 读取对象
DataStore(推荐替代SharedPreferences)
适用场景:轻量级键值存储,支持类型安全和协议缓冲区(Protobuf)。
特点:
- 分为
Preferences DataStore
(兼容SharedPreferences)和Proto DataStore
(支持复杂数据类型)。 - 异步操作,性能更好。
- 分为
存储对象的方式:
使用
Proto DataStore
存储自定义对象。示例:
// 定义数据类(需转换为Protobuf) data class UserProto(val name: String, val age: Int) // 创建DataStore val dataStore = context.createDataStore(type = Preferences.TYPE_PROTO, name = "user_proto") // 存储对象 val user = UserProto("John", 25) lifecycleScope.launch { dataStore.edit { settings -> settings[USER_KEY] = user // 需定义Proto串行化逻辑 } } // 读取对象 lifecycleScope.launch { val user = dataStore.data.first()[USER_KEY] }
存储方式对比
存储类型 | 数据结构 | 适用场景 | 持久化 | 性能 |
---|---|---|---|---|
SharedPreferences | 键值对(基本类型) | 简单配置、轻量级数据 | 是 | 高(读取快) |
文件存储 | 二进制/文本文件 | 复杂对象、文件资源 | 是 | 中等(依赖文件大小) |
SQLite(Room) | 关系型表 | 结构化数据、复杂查询 | 是 | 低(需优化查询) |
DataStore | 键值对(支持Protobuf) | 轻量级数据、类型安全 | 是 | 高(异步优化) |
相关问题与解答
问题1:如何选择存储方式?
- 解答:
- 简单配置:优先使用
DataStore
或SharedPreferences
。 - 复杂对象:文件存储(需序列化)或SQLite(结构化数据)。
- 跨应用共享:使用
ContentProvider
或云端存储。 - 高频读写:
DataStore
或内存缓存(如LiveData
)。
- 简单配置:优先使用
问题2:如何优化SQLite数据库性能?
- 解答:
- 索引优化:为频繁查询的字段添加索引。
- 分页查询:使用
LIMIT
和OFFSET
避免一次性加载大量数据。 - 异步操作:通过
Room
的LiveData
或Coroutine
进行后台操作。 - 数据库迁移:版本更新时处理好表结构变更,避免数据