You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jetpack Compose+Kotlin+Room笔记应用获取当前时间崩溃求助

问题解决方案:Room数据库崩溃与日期格式化优化

一、修复Room数据库崩溃问题

你遇到的崩溃是因为实体类结构变更后未更新数据库版本,Room检测到本地schema与预期哈希值不匹配,触发完整性校验失败。

解决步骤:

  1. 升级数据库版本号:将@Database注解中的version从1改为2
  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:

  1. 启用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")
}
  1. 创建日期格式化工具类:
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)
    }
}
  1. 修改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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 03:25:08