Kotlin Closable and SQLiteDatabase on Android

I use this code in my project

fun getAllData(): List<Data> = writableDatabase.use { db ->
    db.query(...)
}

It runs successfully on Lollipop devices, but on pre-Lollipop it throws a ClassCastException

FATAL EXCEPTION: main
java.lang.ClassCastException: android.database.sqlite.SQLiteDatabase cannot be cast to java.io.Closeable

Perhaps because it is Java 1.6 and does not have a try-with-resources function, but I'm not sure.

So why do I have this exception and how can it be fixed?

+4
source share
1 answer

The problem has nothing to do with try-with resources and is simply an incompatible dependency problem between compiled code and the runtime.

SQLiteDatabase Closeable, , . .

/, , , , JVM. Kotlin , , , Closeable. :

inline fun <T : Closeable, R> T.use(block: (T) -> R): R { ... }

, writableDatabase ( -):

CHECKCAST java/io/Closeable

, SQLiteDatabase Closeable . Android, , . - . , , JAR JVM , . Android JAR.

, ? - use SQLiteDatabase, close ( Kotlin stdlib use):

inline fun <T : SQLiteDatabase, R> T.use(block: (T) -> R): R {
    var closed = false
    try {
        return block(this)
    } catch (e: Exception) {
        closed = true
        try {
            close()
        } catch (closeException: Exception) {
            // eat the closeException as we are already throwing the original cause
            // and we don't want to mask the real exception
       }
        throw e
    } finally {
        if (!closed) {
            close()
        }
    }
}

CHECKCAST android/database/sqlite/SQLiteDatabase, .

+4

Source: https://habr.com/ru/post/1654233/


All Articles