日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

android代码打开数据库,android – 如何正确关闭并重新打开Room数据库

發布時間:2025/3/15 数据库 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 android代码打开数据库,android – 如何正确关闭并重新打开Room数据库 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

您好我有2個應用程序依賴于制作和恢復應用程序數據庫的備份,只需將數據庫文件復制到SD卡中,然后很難確定如何在關閉它之后重新打開Room Database單例以創建數據庫’副本.

構建數據庫:

@Database(version = 15, exportSchema = true, entities = [list of entities])

abstract class AppDatabase : RoomDatabase() {

//list of DAOs

companion object {

@Volatile private var INSTANCE: AppDatabase? = null

fun getInstance(context: Context): AppDatabase =

INSTANCE ?: synchronized(this) {

INSTANCE ?: buildDatabase(context).also {

INSTANCE = it

}

}

private fun buildDatabase(context: Context) =

Room.databaseBuilder(

context.applicationContext,

AppDatabase::class.java,

"Fazendao.sqlitedb"

)

.addMigrations(Migration1315)

.build()

}

}

關閉數據庫:

fun closeDatabase() {

if(db.isOpen) {

db.openHelper.close()

}

}

使數據庫文件復制(在ViewModel中):

fun exportaBkpObservable(nome: String, auto: String, storage: File, database: File) {

disposable.clear()

setFlagsNull()

flagSubject.onNext(false)

disposable.add(

Observable.fromCallable {

repo.recordBkpName(nome)

}

.subscribeOn(Schedulers.io())

.flatMap {

return@flatMap try {

//closing the database

repo.closeDatabase()

Observable.just(

database.copyTo(File(storage, auto), true)

)

.flatMap {

val myDb = SQLiteDatabase.openOrCreateDatabase(it, null)

val ok = myDb.isDatabaseIntegrityOk

if(myDb.isOpen) myDb.close()

if(ok) {

Observable.just(ok)

} else {

Observable.error(Throwable("CORRUPTED DATABASE"))

}

}

} catch (t: Throwable) {

Observable.error(t)

}

}

.subscribe(

{},

{

errorFlag = "exportDB: " + it.message

errorSubject.onNext("exportDB: " + it.message)

},

{

//trying to reopen database

repo.openDatabase()

trueFlag = true

flagSubject.onNext(true)

}

)

)

}

repo是注入AppDatabase的存儲庫,然后在ViewModelFactory中注入.

注射:

object MainInjection {

private fun providesIORepo(context: Context): IORepo {

return IORepo(AppDatabase.getInstance(context))

}

fun provideIOViewModelFactory(context: Context): IOViewModelFactory {

val data = providesIORepo(context)

return IOViewModelFactory(data)

}

}

在AppCompatActivity onCreate中:

val modelFactory = MainInjection.provideIOViewModelFactory(this)

viewModel = ViewModelProviders.of(this, modelFactory).get(IOViewModel::class.java)

重新打開數據庫:

fun openDatabase() {

if(!db.isOpen){

db.openHelper.writableDatabase

}

}

現在錯誤消息:

試圖重新打開數據庫:

E/ROOM: Invalidation tracker is initialized twice :/.

因此當我嘗試從另一個函數訪問它時崩潰:

Cannot perform this operation because the connection pool has been closed.

關閉數據庫后,我有時也會:

E/ROOM: Cannot run invalidation tracker. Is the db closed?

在這篇文章Incrementally migrate from SQLite to Room中,作者為每次訪問它打開和關閉數據庫,所以我不明白為什么我的實現不起作用.

那我在哪里錯了?有沒有辦法停用InvalidationTracker?

我是否應該使用以下代碼關閉數據庫并在每次必須復制數據庫文件時清除Room實例.安全嗎?:

fun destroyInstance() {

if (INSTANCE?.isOpen == true) {

INSTANCE?.close()

}

INSTANCE = null

}

感謝您的關注.

解決方法:

好的,我開始使用以下代碼關閉數據庫:

fun destroyInstance() {

if (INSTANCE?.isOpen == true) {

INSTANCE?.close()

}

INSTANCE = null

}

并實現了如下導入數據庫

fun importaBkpObservable(origin: File, database: File) {

disposable.clear()

setFlagsNull()

flagSubject.onNext(false)

disposable.add(

Observable.fromCallable {

try {

repo.closeDatabase()

val myDb = SQLiteDatabase.openOrCreateDatabase(origin, null)

val ok = myDb.isDatabaseIntegrityOk

if (myDb.isOpen) myDb.close()

if(ok) {

origin.copyTo(database, true)

} else {

"CORRUPTED DATABASE"

}

} catch (t: Throwable) {

t.message

}

}

.subscribeOn(Schedulers.io())

.subscribe(

{

if(it != null) {

if(it is String) {

errorFlag = "exportDB: $it"

errorSubject.onNext("exportDB: $it")

} else {

trueFlag = true

flagSubject.onNext(true)

}

} else {

errorFlag = "exportDB: GENERIC"

errorSubject.onNext("exportDB: GENERIC")

}

},

{

errorFlag = "exportDB: ${it.message}"

errorSubject.onNext("exportDB: ${it.message}")

}

)

)

}

我曾經通過startActivityForResult()從我的主要活動導航到導入/導出活動,但現在已經更改為startActivity()在此調用之后完成我的主要活動.導入/導出完成后,我使用startActivity()調用我的主活動,然后完成導入/導出活動.

這樣我的主要活動ViewModel再次使用新的AppDatabase實例進行實例化,并且一切正常.

我查看了Android Profiler,經過多次導入和導出后,內存使用量介于90 MB到130 MB之間,與之前沒有關閉數據庫時一樣,所以我想我沒有遇到某種內存泄漏或累積Room Databases實例.

我還應該檢查什么?

標簽:android,android-room

來源: https://codeday.me/bug/20190622/1262676.html

總結

以上是生活随笔為你收集整理的android代码打开数据库,android – 如何正确关闭并重新打开Room数据库的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。