Jetpack Compose+Kotlin+Room笔记应用获取当前时间崩溃求助
问题解决方案:Room数据库崩溃与日期格式化优化
一、修复Room数据库崩溃问题
你遇到的崩溃是因为实体类结构变更后未更新数据库版本,Room检测到本地schema与预期哈希值不匹配,触发完整性校验失败。
解决步骤:
- 升级数据库版本号:将
@Database注解中的version从1改为2 - 开发阶段快速恢复:如果是测试环境,添加
fallbackToDestructiveMigration()让Room自动重建数据库(正式环境需编写Migration逻辑,避免数据丢失)
修改后的数据库类代码:
@Database(entities = [Note::class], version = 2, exportSchema = false) @TypeConverters(DateConvertor::class) abstract class NoteDataBase: RoomDatabase() { abstract fun noteDao(): NoteDataBaseDAO companion object { fun getInstance(context: Context): NoteDataBase { return Room.databaseBuilder( context.applicationContext, NoteDataBase::class.java, "note_database" ) .fallbackToDestructiveMigration() // 开发阶段使用,正式版替换为Migration .build() } } }
二、正确获取并格式化日期时间
你的实体类中entryDate的默认值设置是正确的(Date.from(Instant.now())会自动生成当前时间),问题出在日期展示的格式化方式上:直接调用toString()会输出不友好的格式,且之前使用的SimpleDateFormat存在线程安全问题,容易引发崩溃。
优化方案:
推荐使用Java 8+的DateTimeFormatter(线程安全,格式灵活),需先确保项目支持Java 8时间API:
- 启用Desugar支持:在Module级别的
build.gradle.kts中添加配置:
android { compileOptions { coreLibraryDesugaringEnabled = true sourceCompatibility = JavaVersion.VERSION_1_8 targetCompatibility = JavaVersion.VERSION_1_8 } kotlinOptions { jvmTarget = "1.8" } } dependencies { coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.0.4") }
- 创建日期格式化工具类:
import java.time.Instant import java.time.ZoneId import java.time.format.DateTimeFormatter import java.util.Date object DateFormatter { private val formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss") .withZone(ZoneId.systemDefault()) fun formatDate(date: Date): String { val instant = Instant.ofEpochMilli(date.time) return formatter.format(instant) } }
- 修改NoteRow组件的时间展示:
Text( text = DateFormatter.formatDate(note.entryDate), style = MaterialTheme.typography.labelSmall )
可选:实体类替换为现代时间API
如果想彻底抛弃Date类,可以将实体类中的entryDate改为Instant,并更新TypeConverter:
// 修改Note实体类 @Entity("tableOfNotes") data class Note( @PrimaryKey val id: UUID = UUID.randomUUID(), @ColumnInfo("Note_Title") val title: String, @ColumnInfo("Note_Description") val description: String, @ColumnInfo("Note_entryDate") val entryDate: Instant = Instant.now() ) // 更新DateConvertor为InstantConvertor class InstantConvertor { @TypeConverter fun fromTimestamp(value: Long?): Instant? { return value?.let { Instant.ofEpochMilli(it) } } @TypeConverter fun instantToTimestamp(instant: Instant?): Long? { return instant?.toEpochMilli() } } // 数据库类中替换TypeConverter @Database(entities = [Note::class], version = 2, exportSchema = false) @TypeConverters(InstantConvertor::class) abstract class NoteDataBase: RoomDatabase() { // ... 其他代码不变 }
这样可以使用更现代、类型安全的时间API,避免Date类的设计缺陷。
内容的提问来源于stack exchange,提问作者Aarav Bansal
相关产品推荐
相关产品推荐

