最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

android - IllegalStateException: Cannot perform this operation because the connection pool has been closed (Room Database DAO is

programmeradmin1浏览0评论

I'm encountering a Fatal Exception: java.lang.IllegalStateException in my Android application when accessing the Room Database DAO after the database connection pool has been closed.

Inside my database i have suspend function to clean database.


    suspend fun formatAndCleanDatabase(context: Context){
        clearAllData()
        close()
        context.deleteDatabase("app_database")
        clearDatabaseInstance()
    }

When i clearing tables and closing database the flow try get data after closed which i want to how prevent this.

@Dao
interface UserProfileDao {
    @Query("SELECT * FROM user_profile WHERE user_id = :userId")
    fun getProfileFlow(userId: String): Flow<UserProfile>
}

The error occurs after cleaning database. And earlier flow already invoked by view model before cleaning the database is try fetch data from the database using Flow in a DAO method after database is closed and invalidated. Here’s the stack trace:

Fatal Exception: java.lang.IllegalStateException
Cannot perform this operation because the connection pool has been closed.
android.database.sqlite.SQLiteConnectionPool.throwIfClosedLocked (SQLiteConnectionPool.java:1078)

androidx.room.driver.SupportSQLiteStatement$SupportAndroidSQLiteStatement.step (SupportSQLiteStatement.android.kt:183)
com.app.database.daos.profile.UserProfileDao_Impl.getProfileFlow$lambda$2 (UserProfileDao_Impl.kt:148)

I'm encountering a Fatal Exception: java.lang.IllegalStateException in my Android application when accessing the Room Database DAO after the database connection pool has been closed.

Inside my database i have suspend function to clean database.


    suspend fun formatAndCleanDatabase(context: Context){
        clearAllData()
        close()
        context.deleteDatabase("app_database")
        clearDatabaseInstance()
    }

When i clearing tables and closing database the flow try get data after closed which i want to how prevent this.

@Dao
interface UserProfileDao {
    @Query("SELECT * FROM user_profile WHERE user_id = :userId")
    fun getProfileFlow(userId: String): Flow<UserProfile>
}

The error occurs after cleaning database. And earlier flow already invoked by view model before cleaning the database is try fetch data from the database using Flow in a DAO method after database is closed and invalidated. Here’s the stack trace:

Fatal Exception: java.lang.IllegalStateException
Cannot perform this operation because the connection pool has been closed.
android.database.sqlite.SQLiteConnectionPool.throwIfClosedLocked (SQLiteConnectionPool.java:1078)

androidx.room.driver.SupportSQLiteStatement$SupportAndroidSQLiteStatement.step (SupportSQLiteStatement.android.kt:183)
com.app.database.daos.profile.UserProfileDao_Impl.getProfileFlow$lambda$2 (UserProfileDao_Impl.kt:148)
Share Improve this question edited Feb 6 at 12:04 Santhosh Kumar asked Feb 6 at 11:40 Santhosh KumarSanthosh Kumar 5111 silver badge11 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 1

Deleting the entire database while it is currently in use is an unusual thing to do, so I doubt there is an official recommendation how to handle that. But you can always catch the exception and process it accordingly.

Assuming your view model transforms the database flow in a StateFlow of UiState, you can do something like this:

sealed interface UiState {
    data object Loading : UiState
    data class Success(val profile: UserProfile) : UiState
    data object NoDatabase : UiState
}

class MyViewModel(dao: UserProfileDao, userId: String) : ViewModel() {
    val uiState: StateFlow<UiState> = dao.getProfileFlow(userId)
        .mapLatest(UiState::Success)
        .catch<UiState> {
            if (it !is IllegalStateException) throw it
            emit(UiState.NoDatabase)
        }
        .stateIn(
            scope = viewModelScope,
            started = SharingStarted.WhileSubscribed(5.seconds),
            initialValue = UiState.Loading,
        )
}

Your UI can then react accordingly and display what needs to be displayed when the database was deleted.

You would need to do something similar to all other dao functions that also return a flow.

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论