上一篇
安卓开发数据库传输数据
- 行业动态
- 2025-04-22
- 3562
安卓数据库传输数据基础
本地数据库类型
数据库类型 | 特点 | 适用场景 |
---|---|---|
SQLite | 轻量级嵌入式数据库,支持SQL语法 | 本地数据存储(如用户信息、设置) |
Room | 基于SQLite的抽象层,提供编译时检查 | 复杂数据操作,需类型安全的场景 |
数据传输核心流程
- 读取数据:通过
SQLiteDatabase
或Room
的@Query
从数据库获取数据 - 数据转换:将
Cursor
或LiveData
转换为可传输对象(如List、自定义Model) - 选择传输方式:
- 本地组件间:Intent/Bundle/ViewModel
- 跨进程/网络:JSON/Protobuf + Retrofit/OkHttp
本地组件间数据传输方案
使用ViewModel共享数据
// 定义共享数据类 data class User(val id: Int, val name: String) // ViewModel中暴露LiveData class SharedViewModel : ViewModel() { private val repository = UserRepository() val users: LiveData<List<User>> = repository.getAllUsers() } // Activity中观察数据 viewModel.users.observe(this) { userList -> // 将数据传递给Fragment或Adapter }
Bundle传值限制
特性 | Bundle | Parcelable | Serializable |
---|---|---|---|
性能 | 最快 | 中等 | 最慢 |
类型安全 | 无 | 有 | 无 |
支持对象 | 基本类型/String | 复杂对象 | 所有序列化对象 |
网络传输实践
Retrofit+Room协同
// Room实体 @Entity data class Note( @PrimaryKey val id: Int, val content: String, val syncStatus: Int // 0:未同步 1:已同步 ) // DAO接口 @Dao interface NoteDao { @Query("SELECT FROM note WHERE syncStatus = 0") fun getUnsyncedNotes(): LiveData<List<Note>> @Update fun updateSyncStatus(note: Note) } // 网络API interface ApiService { @POST("notes/sync") suspend fun syncNotes(@Body notes: List<Note>): Response<Void> } // 同步流程 viewModelScope.launch { val unsyncedNotes = noteDao.getUnsyncedNotes().value ?: return@launch try { apiService.syncNotes(unsyncedNotes) // 更新本地状态 unsyncedNotes.forEach { it.syncStatus = 1 noteDao.updateSyncStatus(it) } } catch (e: Exception) { // 错误处理 } }
数据转换策略对比
方案 | 性能 | 兼容性 | 开发效率 |
---|---|---|---|
Gson | 中等 | 高(广泛支持) | 高(注解简单) |
Moshi | 高 | 高 | 中(需手动配置) |
Protobuf | 高 | 低(需.proto编译) | 低(学习成本高) |
常见问题解决方案
大数据量传输卡顿
- 分页加载:使用
Limit/Offset
或游标分页
- 异步处理:在子线程执行查询,主线程更新UI
- 数据压缩:传输前进行GZIP压缩(适合网络传输)
数据一致性保障
- 事务处理:使用
database.beginTransaction()
保证原子性 - 版本控制:通过
Migration
处理数据库升级 - 冲突策略:Room支持
OnConflictStrategy
(如REPLACE/ABORT)
相关问题与解答
Q1:如何在Activity销毁时保存数据库查询状态?
解答:
使用ViewModel
+LiveData
持久化查询结果,或在onSaveInstanceState()
中保存关键参数:
override fun onSaveInstanceState(outState: Bundle) { super.onSaveInstanceState(outState) outState.putInt("lastId", currentId) // 保存当前查询ID }
恢复时重新发起查询:
if (savedInstanceState != null) { currentId = savedInstanceState.getInt("lastId") viewModel.queryData(currentId) }
Q2:网络传输时如何防止明文数据泄露?
解答:
- 数据加密:使用HTTPS+证书校验,敏感字段单独AES加密
- 密钥管理:通过Keystore存储密钥,使用Android Keystore System
- 签名验证:对传输数据生成HMAC签名,服务端验证完整性
- 防重放攻击:添加时间戳+随机数,服务端验证时效