Reputation: 1322
I'm creating a content provider in Kotlin that uses a DB for store data and query them with a loaders, the problem is, that I need my DBHelper variable be reachable from any function: onCreate, query, update, etc... In java this is easy but in Kotlin the IDE tells me that I must initialize the val, I tried using init blocks but android studio says that the DBHelper must be initialized in onCreate()
So, How can I create a val in Kotlin that is reacheable for any function in the class and can be initialized in onCreate function like Java?
This is my code:
public class ProviderMMR : ContentProvider() {
var dbHelper
companion object Matcher{
var uriMatcher = UriMatcher(UriMatcher.NO_MATCH)
init{
uriMatcher.addURI(MMDContract.columnas.AUTHORITY,MMDContract.columnas.TABLA_FARMACIA,1)
}
}
override fun onCreate(): Boolean {
dbHelper = mmrbd(context)
return true
}
override fun insert(uri: Uri?, values: ContentValues?): Uri {
val db = dbHelper.writableDatabase
val rowID = db.insert(MMDContract.columnas.TABLA_FARMACIA, null, values)
val uri_actividad = ContentUris.withAppendedId(MMDContract.columnas.CONTENT_BASE_URI, rowID)
return uri_actividad
}
override fun query(uri: Uri?, projection: Array<out String>?, selection: String?, selectionArgs: Array<out String>?, sortOrder: String?): Cursor {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
override fun update(uri: Uri?, values: ContentValues?, selection: String?, selectionArgs: Array<out String>?): Int {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
override fun delete(uri: Uri?, selection: String?, selectionArgs: Array<out String>?): Int {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
override fun getType(uri: Uri?): String {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
}
Upvotes: 5
Views: 11208
Reputation: 5157
If you are using "dbHelper" from multiple places it's better to use lazy initializer so the variable can have value once and initialized once called and if you're not using the "dbHelper" from multiple threads you can add LazyThreadSafetyMode.NONE to lazy initializer to gain more performance. for more info: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-lazy-thread-safety-mode/-n-o-n-e.html
val uri by lazy(LazyThreadSafetyMode.NONE){
mmrbd(context)
}
if you're going to use lateinit you have to use var and in your case, it's better to add private set so the variable not initialized for outside of the class
class ProviderMMR : ContentProvider() {
companion object {
lateinit var dbHelper: mmrbd
private set
}
override fun onCreate() {
super.onCreate()
dbHelper= mmrbd(context)
}
}
Upvotes: 0
Reputation: 763
Well you can achieve it 2-3 ways, so in Kotlin we have have the delegates which lets you initialize the variable on its first access i.e. the variable gets initialized whenever it is first used, so you can do
val dbHelper by lazy { mmrbd(context) }
Or you can do that in a Java way you can say:
var dbHelper: mmrbd? = null
and initialize it in OnCreate like: dbHelper = mmrbd(context)
Or you can use the lateinit keyword of Kotlin which basically lets you initialize the variable later, but its your responsiblity to initialize it before you use the variable:
lateinit var dbHelper: mmrbd
and initialize it in OnCreate like: dbHelper = mmrbd(context)
Upvotes: 4
Reputation: 17248
You can also use lazy delegate, which will create your dbHelper object on first access
val dbHelper by lazy { mmrbd(context) }
Upvotes: 10
Reputation: 1408
You can use lateinit var
and initialize it in onCreate.
Check Late-Initialized Properties and Variables here for reference.
https://kotlinlang.org/docs/reference/properties.html
Upvotes: 7