6

I came up with the following problem:

My MainActivity code:

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // ...
        // ERROR: Cannot create instance of an abstract class
        var db = DataBase().getDataBase(this)
        // ...
    }
}

Room's Database:

@Database(entities = arrayOf(DataBaseUser::class), version = 1)
abstract class DataBase : RoomDatabase() {

    val DB_NAME : String = "DataBaseUser"
    private lateinit var INSTANCE : DataBase

    fun getDataBase(context: Context): DataBase {
        if (INSTANCE == null){
            INSTANCE = Room.databaseBuilder(context.applicationContext,DataBase::class.java,DB_NAME).build()
        }
        return INSTANCE
    }

    abstract fun getUserDao(): DataBaseUserDao
}

I can not instantiate the class in Kotlin. In Java I did it like this:

db = AppDataBase.getDataBase(view.getContext());

How can I get the same result in Kotlin?

Willi Mentzel
  • 27,862
  • 20
  • 113
  • 121
  • Possible duplicate of [Can we instantiate an abstract class?](https://stackoverflow.com/questions/4579305/can-we-instantiate-an-abstract-class) – Vlad Dec 14 '17 at 13:18

3 Answers3

13

Use a singleton (in Kotlin object) to hold the Room database instance:

@Database(entities = arrayOf(DataBaseUser::class), version = 1)
abstract class DataBase : RoomDatabase() {
    abstract fun getUserDao(): DataBaseUserDao
}

object DatabaseProvider {
  private const val DB_NAME: String = "DataBaseUser"
  private lateinit var dbInstance: DataBase

  fun getDatabase(context: Context): DataBase {

    if (!this::dbInstance.isInitialized) {
      dbInstance = Room.databaseBuilder(
        context.applicationContext,
        DataBase::class.java,
        DB_NAME
      ).build()
    }

    return dbInstance
  }
}

Usage:

val db = DatabaseProvider.getDatabase(view.getContext())
Willi Mentzel
  • 27,862
  • 20
  • 113
  • 121
3

For instantiate abstract class in Kotlin you use object: <your class>. Example:

abstract class AbstractTest {
    abstract fun someFun(): Int
}

fun main(args: Array<String>) {
    val astractInstance = object : AbstractTest() {
        override fun someFun(): Int {
            TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
        }
    }
}
kurt
  • 1,510
  • 2
  • 13
  • 23
1

You can use below

var db = object: DataBase(){
    override fun getUserDao(): DataBase{
    TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
    }
}
Ergin Ersoy
  • 890
  • 8
  • 28