Android 如果已有房间数据库实例,如何填充该数据库?
我希望我的用户能够将房间数据库保存在谷歌硬盘上,然后从另一台设备上加载,第一部分已经实现,但我正在努力用新文件填充房间数据库 这是我的数据库单例:Android 如果已有房间数据库实例,如何填充该数据库?,android,kotlin,android-room,Android,Kotlin,Android Room,我希望我的用户能够将房间数据库保存在谷歌硬盘上,然后从另一台设备上加载,第一部分已经实现,但我正在努力用新文件填充房间数据库 这是我的数据库单例: companion object { @Volatile private var INSTANCE: AppRoomDataBase? = null fun getDatabase(context: Context): AppRoomDataBase { val tempInstance = INSTANCE
companion object {
@Volatile
private var INSTANCE: AppRoomDataBase? = null
fun getDatabase(context: Context): AppRoomDataBase {
val tempInstance = INSTANCE
if (tempInstance != null) {
return tempInstance
}
synchronized(this) {
val instance = Room.databaseBuilder(
context.applicationContext,
AppRoomDataBase::class.java,
"product_database"
).build()
INSTANCE = instance
return instance
}
}
}
然后,当用户希望从google drive加载数据库时:
private fun loadFileFromDrive() {
val file = File(getExternalFilesDir(null), "product_database")
mDriveServiceHelper.queryFiles().addOnSuccessListener { fileList ->
val database = fileList.files.first()
mDriveServiceHelper.downloadFile(file,database.id)?.addOnSuccessListener {
prepopulateRoomDatabaseWithFile(file)
}
}
}
private fun prepopulateRoomDatabaseWithFile(file : File){
Room.databaseBuilder(application,AppRoomDataBase::class.java,"product_database")
.createFromFile(file)
.build()
}
但它不起作用,只有关于如何从文件中创建数据库的文档,但我找不到任何关于如何仅在需要时使用新的文件室数据库覆盖当前文件室数据库的内容,是否可能?我认为您需要关闭原始数据库,然后构建第二个数据库设置实例 下面是一个示例(仅通过关闭然后重新打开单个数据库进行测试,请参见下面的示例)
- 注意:为了方便和简洁,已使用allowMainThreadQueries
D/USERINFODB1: UserId = 0 UserName = UserFred
D/USERINFODB2: UserId = 0 UserName = UserFred
我尝试了MikeT解决方案,但它不起作用,因为我有许多不同的地方使用房间数据库,在每个地方我都必须传递一个信息,即应该使用新的数据库 对于我的案例,更好的解决方案是通过删除前一个数据库文件并将已加载的文件移动到旧数据库的目录中来切换数据库文件,如下所示:
private fun swapDatabaseFiles(file: File){
AppRoomDataBase.getDatabase(applicationContext).close()
databaseFile.delete()
copyFile(file.absolutePath,databaseFile.name,databaseFile.absolutePath)
prepopulateRoomDatabaseWithFile(file) // TO OPEN DATABASE
val mainActivity = Intent(applicationContext,MainActivity::class.java) // NOW RESTARTING ACTIVITY SO DATABASE IS REFRESHED
mainActivity.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
startActivity(mainActivity)
}
private fun copyFile(inputPath: String, inputFileName: String, outputPath: String) {
var inputStream: InputStream?
var out: OutputStream?
try {
inputStream = FileInputStream(inputPath)
out = FileOutputStream(outputPath + inputFileName)
val buffer = ByteArray(1024)
var read: Int
while (inputStream.read(buffer).also { read = it } != -1) {
out.write(buffer, 0, read)
}
inputStream.close()
// write the output file (You have now copied the file)
out.flush()
out.close()
} catch (fnfe1: FileNotFoundException) {
fnfe1.message?.let { Log.e("tag fnfe1", it)
}
} catch (e: Exception) {
Log.e("tag exception", e.message!!)
}
}
在数据库的单例中交换数据库函数:
fun swapDatabase(context: Context,file : File){
INSTANCE?.close()
INSTANCE = null
synchronized(this){
val instance = Room.databaseBuilder(context.applicationContext,AppRoomDataBase::class.java,"product_database")
.createFromFile(file)
.build()
INSTANCE = instance
}
}
编辑:重构代码并修复错误异常。现在一切正常。您的解决方案是正确的,但在我的情况下不是这样,首先,如果您使用不同的数据库,您会发现它不工作,因为dao没有更新,其次,使用这种方法,我需要在我使用它的每个地方存储对新数据库的引用。
private fun swapDatabaseFiles(file: File){
AppRoomDataBase.getDatabase(applicationContext).close()
databaseFile.delete()
copyFile(file.absolutePath,databaseFile.name,databaseFile.absolutePath)
prepopulateRoomDatabaseWithFile(file) // TO OPEN DATABASE
val mainActivity = Intent(applicationContext,MainActivity::class.java) // NOW RESTARTING ACTIVITY SO DATABASE IS REFRESHED
mainActivity.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
startActivity(mainActivity)
}
private fun copyFile(inputPath: String, inputFileName: String, outputPath: String) {
var inputStream: InputStream?
var out: OutputStream?
try {
inputStream = FileInputStream(inputPath)
out = FileOutputStream(outputPath + inputFileName)
val buffer = ByteArray(1024)
var read: Int
while (inputStream.read(buffer).also { read = it } != -1) {
out.write(buffer, 0, read)
}
inputStream.close()
// write the output file (You have now copied the file)
out.flush()
out.close()
} catch (fnfe1: FileNotFoundException) {
fnfe1.message?.let { Log.e("tag fnfe1", it)
}
} catch (e: Exception) {
Log.e("tag exception", e.message!!)
}
}
fun swapDatabase(context: Context,file : File){
INSTANCE?.close()
INSTANCE = null
synchronized(this){
val instance = Room.databaseBuilder(context.applicationContext,AppRoomDataBase::class.java,"product_database")
.createFromFile(file)
.build()
INSTANCE = instance
}
}