I'm learning Kotlin from "Kotlin in Action" and I'm slowly converting an Android app code to it. But I have found some problem in converting the following class.
public class DatabaseController {
private static DatabaseController sDatabaseController;
private SQLiteDatabase mDatabase;
private DatabaseController(Context context) {
mDatabase = new SQLiteOpenHelperImpl(context.getApplicationContext())
.getWritableDatabase();
}
public static DatabaseController getDatabaseController(Context context) {
if (sDatabaseController == null) {
sDatabaseController = new DatabaseController(context);
}
return sDatabaseController;
}
public void addElement(Element element) {
if (element != null) {
ContentValues values = getContentValues(element);
mDatabase.beginTransaction();
try {
// insert element
mDatabase.setTransactionSuccessful();
} finally {
mDatabase.endTransaction();
}
}
}
I've come up with two different Kotlin implementation, but neither of them fully convince me. Which one can be considered a better solution? Or does exist a third one that is better?
First implementation using object
object DatabaseControllerObject {
private var mDatabase : SQLiteDatabase? = null
fun initDatabase(context: Context) {
mDatabase = mDatabase?: SQLiteOpenHelperImpl(context.applicationContext).writableDatabase
}
fun addElement(context: Context, element: Element) {
initDatabase(context)
// insert alarm
mDatabase?.let {
// CODE
}
}
Second implementation with everything in a single file, where I call initDatabase(..) in the onCreate() of each activity that needs the database
private var mDatabase: SQLiteDatabase? = null
fun initDatabase(context: Context) {
mDatabase = mDatabase ?: SQLiteOpenHelperImpl(context.applicationContext).writableDatabase
}
fun addElement(element: Element) {
val values = getContentValues(element)
mDatabase?.let {
it.beginTransaction()
try {
// insert
it.setTransactionSuccessful()
} finally {
it.endTransaction()
}
}
}
In Kotlin, we need to use the object keyword to use Singleton class. The object class can have functions, properties, and the init method. The constructor method is not allowed in an object so we can use the init method if some initialization is required and the object can be defined inside a class.
If we especially conversation around Android, we know that in Android we by and large have to pass a context instance to init block of a singleton. We can do it by using Early initialization and Apathetic initialization. In early initialization, all the components are initialized within the Application.
In short, companion objects are singleton objects whose properties and functions are tied to a class but not to the instance of that class — basically like the “static” keyword in Java but with a twist.
Using Singletons in Kotlin. By using the keyword object in your app, you're defining a singleton. A singleton is a design pattern in which a given class has only one single instance inside the entire app.
I think what you want is a companion object:
class DatabaseController
{
private constructor(context: Context)
{
// ...
}
companion object
{
private var instance: DatabaseController? = null
fun getInstance(context: Context): DatabaseController
{
if(instance == null)
{
instance = DatabaseController(context)
}
return instance!!
}
}
}
Then you can just call it like this:
val databaseController = DatabaseController.getInstance(context)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With