Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 空间回退到破坏性迁移_Android_Kotlin_Android Room - Fatal编程技术网

Android 空间回退到破坏性迁移

Android 空间回退到破坏性迁移,android,kotlin,android-room,Android,Kotlin,Android Room,我熟悉了Room,并试图通过读取资产文件夹中的数据库来组装一个小项目。面临这样一个问题:当抛出数据库的一个版本时,它抛出一个异常并要求添加迁移。在提升版本时,我只需从资产中重写数据库就足够了。为此,码头中有一个回退到破坏性迁移()的方法。但当我在构建器中指定它时,实际上每次应用程序启动时,我的数据库都会被覆盖。我需要的是,只有在提升应用程序版本时,才从资产重写数据库。我不明白如何实现这种行为。我将非常感谢你的帮助 我就是这样做的: 这是最简单的例子 道: 数据库 @Database(ve

我熟悉了Room,并试图通过读取资产文件夹中的数据库来组装一个小项目。面临这样一个问题:当抛出数据库的一个版本时,它抛出一个异常并要求添加迁移。在提升版本时,我只需从资产中重写数据库就足够了。为此,码头中有一个回退到破坏性迁移()的方法。但当我在构建器中指定它时,实际上每次应用程序启动时,我的数据库都会被覆盖。我需要的是,只有在提升应用程序版本时,才从资产重写数据库。我不明白如何实现这种行为。我将非常感谢你的帮助

我就是这样做的:

这是最简单的例子

道:

数据库

    @Database(version = 2, entities = [Name::class])
abstract class AppDatabase : RoomDatabase() {
    abstract fun nameDao(): NameDao
}
POJO实体

@Entity(tableName = "tips_of_the_day")
data class Name(
    @ColumnInfo(name = "name")
    var name: String?
) {
    @PrimaryKey(autoGenerate = true)
    @ColumnInfo(name = "_id")
    var id: Int = 0
}
应用程序类

class App : Application() {
private lateinit var appDatabase: AppDatabase


override fun onCreate() {
    super.onCreate()
    appDatabase = getAppDatabase()
}

 fun getAppDatabase(): AppDatabase {

    return Room.databaseBuilder(
        this,
        AppDatabase::class.java, DATABASE_NAME
    )
        .createFromAsset("database/tips_of_the_day.db")
        .fallbackToDestructiveMigration()
        .allowMainThreadQueries()
        .build().also { appDatabase = it }

}

companion object {
    private const val DATABASE_NAME = "tips_of_the_day.db"
}
}
还有我的活动

val db: AppDatabase = (application as App).getAppDatabase()
    val dataBase = db.nameDao()


    textView.setOnClickListener(){
        val name: Name = Name( "Anton")
        dataBase.insertMe(name)
        val tableSize: Int = dataBase.all.size
        toast("db size  : $tableSize")
        Log.d("TAG" , "db size  : $tableSize")
    }
事实证明,在重新启动应用程序之前,代码一直有效,然后默认情况下数据库被覆盖并成为新的(


我不希望出现这种行为。我需要保存数据库,直到版本更新。如何实现这一点?

我知道这似乎是一种解决问题的肮脏方法,但您可以手动管理迁移或不迁移问题:

fun getAppDatabase(context: Context): AppDatabase {
        // is migration really needed?
        val db = SQLiteDatabase.openDatabase(context.getDatabasePath(DATABASE_NAME).path, null, SQLiteDatabase.OPEN_READONLY)
        val needToMigrate = db.version < dbVersion // your actual version, could be constant
        db.close()
        return Room.databaseBuilder(context, AppDatabase::class.java, DATABASE_NAME)
            .allowMainThreadQueries().apply {
            if (needToMigrate) this.createFromAsset(DATABASE_DIR)
                .fallbackToDestructiveMigration()
        }.build()
    }
fun getAppDatabase(context:context):AppDatabase{
//真的需要移民吗?
val db=SQLiteDatabase.openDatabase(context.getDatabasePath(数据库名称).path,null,SQLiteDatabase.OPEN\u只读)
val needToMigrate=db.version
只是澄清一下-当您将数据库类中的版本号更改为下一个数字时(例如“2”),您是否也将附加数据库从资产文件夹更改为更新版本2?@sergiytikhonov即使我不更改版本号,也不接触数据库,我的应用程序在每次启动时都会覆盖数据。我不希望出现这种行为。我需要保存数据库,直到版本更新。如何实现这一点?
fun getAppDatabase(context: Context): AppDatabase {
        // is migration really needed?
        val db = SQLiteDatabase.openDatabase(context.getDatabasePath(DATABASE_NAME).path, null, SQLiteDatabase.OPEN_READONLY)
        val needToMigrate = db.version < dbVersion // your actual version, could be constant
        db.close()
        return Room.databaseBuilder(context, AppDatabase::class.java, DATABASE_NAME)
            .allowMainThreadQueries().apply {
            if (needToMigrate) this.createFromAsset(DATABASE_DIR)
                .fallbackToDestructiveMigration()
        }.build()
    }