上一篇
安卓开发修改数据
- 行业动态
- 2025-04-23
- 3169
通过SharedPreferences.Editor或SQLiteDatabase.update,调用put/commit/apply等方法,注意权限和同步处理
安卓开发中修改数据的常见方式与注意事项
本地数据存储与修改
存储方式 | 适用场景 | 修改方法示例 |
---|---|---|
SharedPreferences | 轻量级键值对(如用户设置、登录状态) | SharedPreferences.Editor editor = sp.edit();<br>editor.putString("key", "value");<br>editor.apply(); |
SQLite数据库 | 结构化数据(如用户信息、订单列表) | 通过SQLiteDatabase 的update() 或execSQL() 执行SQL语句,或使用ContentValues 封装数据 |
Room持久化库 | 复杂数据库操作(推荐替代SQLite) | 定义@Dao 接口,使用@Update 注解或自定义方法(如updateUser(User...) ) |
文件存储 | 多媒体、配置文件等(如图片、JSON) | 通过FileOutputStream 写入文件,或使用FileUtils 修改文件内容 |
DataStore | 异步键值存储(替代SharedPreferences) | 使用EditContext 提交修改(如edit.set(key, value).commit() ) |
网络数据修改与同步
RESTful API调用
- 使用
Retrofit
或OkHttp
发送PUT
/PATCH
请求修改服务器数据 - 示例:
@PUT("/user/{id}") Call<User> updateUser(@Path("id") int id, @Body User user);
- 使用
WebSocket实时同步
- 通过
OkHttpWebSocket
或第三方库(如Socket.IO)实现双向通信 - 需处理消息冲突(如版本号校验或乐观锁)
- 通过
本地与网络数据合并
- 使用
Room
的@Relation
关联查询,结合LiveData
监听变化 - 示例流程:
- 从网络获取最新数据
- 与本地数据库对比(如通过
@PrimaryKey
或@Unique
约束) - 调用
insert/update
方法更新本地数据
- 使用
关键注意事项
线程安全
- 数据库操作需在子线程执行(如
Executors.newSingleThreadExecutor()
) - Room默认支持异步RxJava或LiveData,避免直接阻塞UI线程
- 数据库操作需在子线程执行(如
事务管理
- SQLite需手动开启事务(
beginTransaction()
/setTransactionSuccessful()
/endTransaction()
) - Room自动处理事务,但批量操作建议使用
@Transaction
注解
- SQLite需手动开启事务(
数据一致性
- 修改前检查数据存在性(如
SELECT
查询或ContentValues.putNullPolicy(null)
) - 网络修改需处理离线缓存与冲突(如使用
@Sync
注解或自定义冲突策略)
- 修改前检查数据存在性(如
权限管理
- 文件/数据库修改需声明
WRITE_EXTERNAL_STORAGE
或INTERNET
权限 - Android 10+需处理分区存储(Scoped Storage)限制
- 文件/数据库修改需声明
代码示例(Room更新数据)
// DAO接口定义 @Dao public interface UserDao { @Update void updateUser(User... users); // 支持批量更新 } // 使用示例 User user = ...; // 获取需要修改的用户对象 user.setName("New Name"); // 修改字段 new Thread(() -> userDao.updateUser(user)).start(); // 子线程执行
相关问题与解答
问题1:如何避免Room数据库并发修改导致的数据丢失?
解答:
- 使用
@Transaction
注解包裹多个操作,确保原子性 - 调用
copyToRealmOrUpdate()
等方法覆盖旧数据 - 结合
LiveData
观察数据变化,在onActive()
中触发更新 - 服务端可添加版本号或时间戳字段,客户端更新时校验冲突
问题2:修改SharedPreferences后何时生效?
解答:
editor.commit()
:同步提交,立即生效但可能阻塞主线程editor.apply()
:异步提交,推荐用于非关键数据(如配置项)- 若需立即读取修改后的值,需等待
apply()
的SharedPreferences.OnSharedPreferenceChangeListener
回调