CrimeLab in Kotlin


#1

So far, I’ve been able to complete every chapter and challenge in the book in Kotlin. However, I’m stumped on how to convert the code in chapter 14.

Here’s what I have so far:

object CrimeLab {

    private val crimes = mutableListOf<Crime>()

    fun addCrime(c: Crime) {
        crimes.add(c)
    }

    fun deleteCrime(c: Crime) {
        crimes.remove(c)
    }

    fun getCrimes(): List<Crime> {
        return crimes
    }

    fun getCrime(id: UUID): Crime? {
        return crimes.firstOrNull { crime -> crime.id == id }
    }
}

At this point, I need to initialize the database. The book has this in the class constructor. However, objects in Kotlin don’t have constructors per se. I can add an init block, but I won’t be able to pass the context as an argument.

I tried refactoring this to a class with a companion object like so:

class CrimeLab private constructor(private val context: Context) {

    private val crimes = mutableListOf<Crime>()

    fun addCrime(c: Crime) {
        crimes.add(c)
    }

    fun deleteCrime(c: Crime) {
        crimes.remove(c)
    }

    fun getCrimes(): List<Crime> {
        return crimes
    }

    fun getCrime(id: UUID): Crime? {
        return crimes.firstOrNull { crime -> crime.id == id }
    }

    companion object {
        private var crimeLab: CrimeLab? = null

        fun get(context: Context): CrimeLab {
            if (crimeLab == null) {
                crimeLab = CrimeLab(context)
            }

            return crimeLab!!
        }
    }
}

However, now I get a warning on the first line of the companion object:

Do not place Android context classes in static fields (static reference to CrimeLab which has field context pointing to Context); this is a memory leak (and also breaks Instant Run)

How can I refactor this?

Edit: I just realized the same warning occurs if the class is written in Java, so it’s not a Kotlin issue. Maybe it’s a new warning?