androidkotlinkotlin-lateinit

Where can I put the method isInitalized to check the lateinit variable?


I am making an app in Android Studio with Kotlin. With the lateinit variable in the ListFragment throws me an error called:

kotlin.uninitializedpropertyaccessexception: lateinit property dbhelper has not been initialized.

I know that there is a form to check the lateinit with the method (isInitialized).

The class carsDBHelper:

class CochesDBHelper (context: Context) : SQLiteOpenHelper(context, DATABASE_NAME, null,             DATABASE_VERSION) {
    val cars = ArrayList<Cars>()
    companion object {
        // If you change the database schema, you must increment the database version.
        const val DATABASE_VERSION = 1
        const val DATABASE_NAME = "cars.db"
    }   

ListFragment, the class in which, we call CarsDBHelper:

companion object{
    lateinit var dbHelper: CarsDBHelper
 }

val list= dbHelper.getAllCars()

val recyclerView: RecyclerView = v.findViewById(R.id.recyclerView);
recyclerView.layoutManager = LinearLayoutManager(context)

val adapter: RecyclerViewAdapter = RecyclerViewAdapter(list, 
context);
recyclerView.adapter = adapter

I tried to make a method in CarsDBhelper, and in the ListFragment class, but throws me another error.

fun addElement(element: String) {
    if (!::cars.isInitialized) {
      cars= MutableList<String>();
    }

    cars.add(element);
}

And I tried to check under the variable as I saw on another post but it didn't work.

lateinit var dbHelper: CochesDBHelper;
if (::dbHelper.isInitialized) { //in this line throws this error: Expecting member declaration

}

Solution

  • Your database should be a singleton, so the lateinit pattern is not right for this. You should change your database helper to have a private constructor and then create it as a singleton in its own companion object.

    class CochesDBHelper private constructor(
        context: Context
    ) : SQLiteOpenHelper(context, DATABASE_NAME, null, DATABASE_VERSION) {
        
        companion object {
            const val DATABASE_VERSION = 1
            const val DATABASE_NAME = "cars.db"
    
            @Volatile 
            private var INSTANCE: CochesDBHelper? = null
    
            fun getInstance(context: Context): CochesDBHelper {
                return INSTANCE ?: synchronized(this) {
                    INSTANCE ?: CochesDBHelper(context).also { INSTANCE = it }
                }
            }
        }   
    
        //...
    }
    

    Then whenever you need to access it, you will call CochesDBHelper.getInstance() with the context.

    // In fragment:
    
    val dbHelper = CochesDBHelper.getInstance(requireContext())
    
    val list = dbHelper.getAllCars()
    //...