Can anytime AppDatabase in Android Room be null?
up vote
0
down vote
favorite
While adding Room Database, it is suggested to use Singleton Design Pattern
Note: You should follow the singleton design pattern when instantiating an AppDatabase object, as each RoomDatabase instance is fairly expensive, and you rarely need access to multiple instances.
So, adding Room Database, following Google example which is written in Java, in will be as below
private var INSTANCE: AppDatabase? = null
fun getInstance(context: Context): AppDatabase? {
if (INSTANCE == null){
synchronized(AppDatabase::class){
INSTANCE = Room.databaseBuilder(context.applicationContext,
AppDatabase::class.java, "app_database")
.build()
}
}
return INSTANCE
}
When I call getInstance
, compiler suggests that getInstance
can be null
. So my question is there any case that getInstance
be null
and do I have to check if it's null
. If not, then how should I instantiate AppDatabase
so that getInstance
return AppDatabase
not AppDatabase?
and it fits documentation recommendation?
kotlin singleton
add a comment |
up vote
0
down vote
favorite
While adding Room Database, it is suggested to use Singleton Design Pattern
Note: You should follow the singleton design pattern when instantiating an AppDatabase object, as each RoomDatabase instance is fairly expensive, and you rarely need access to multiple instances.
So, adding Room Database, following Google example which is written in Java, in will be as below
private var INSTANCE: AppDatabase? = null
fun getInstance(context: Context): AppDatabase? {
if (INSTANCE == null){
synchronized(AppDatabase::class){
INSTANCE = Room.databaseBuilder(context.applicationContext,
AppDatabase::class.java, "app_database")
.build()
}
}
return INSTANCE
}
When I call getInstance
, compiler suggests that getInstance
can be null
. So my question is there any case that getInstance
be null
and do I have to check if it's null
. If not, then how should I instantiate AppDatabase
so that getInstance
return AppDatabase
not AppDatabase?
and it fits documentation recommendation?
kotlin singleton
add a comment |
up vote
0
down vote
favorite
up vote
0
down vote
favorite
While adding Room Database, it is suggested to use Singleton Design Pattern
Note: You should follow the singleton design pattern when instantiating an AppDatabase object, as each RoomDatabase instance is fairly expensive, and you rarely need access to multiple instances.
So, adding Room Database, following Google example which is written in Java, in will be as below
private var INSTANCE: AppDatabase? = null
fun getInstance(context: Context): AppDatabase? {
if (INSTANCE == null){
synchronized(AppDatabase::class){
INSTANCE = Room.databaseBuilder(context.applicationContext,
AppDatabase::class.java, "app_database")
.build()
}
}
return INSTANCE
}
When I call getInstance
, compiler suggests that getInstance
can be null
. So my question is there any case that getInstance
be null
and do I have to check if it's null
. If not, then how should I instantiate AppDatabase
so that getInstance
return AppDatabase
not AppDatabase?
and it fits documentation recommendation?
kotlin singleton
While adding Room Database, it is suggested to use Singleton Design Pattern
Note: You should follow the singleton design pattern when instantiating an AppDatabase object, as each RoomDatabase instance is fairly expensive, and you rarely need access to multiple instances.
So, adding Room Database, following Google example which is written in Java, in will be as below
private var INSTANCE: AppDatabase? = null
fun getInstance(context: Context): AppDatabase? {
if (INSTANCE == null){
synchronized(AppDatabase::class){
INSTANCE = Room.databaseBuilder(context.applicationContext,
AppDatabase::class.java, "app_database")
.build()
}
}
return INSTANCE
}
When I call getInstance
, compiler suggests that getInstance
can be null
. So my question is there any case that getInstance
be null
and do I have to check if it's null
. If not, then how should I instantiate AppDatabase
so that getInstance
return AppDatabase
not AppDatabase?
and it fits documentation recommendation?
kotlin singleton
kotlin singleton
edited 12 hours ago
Jayson Minard
35.5k13103170
35.5k13103170
asked Nov 5 at 6:26
musooff
869
869
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
up vote
1
down vote
accepted
Use something like this to make sure it is not null
object DatabaseSource {
private lateinit var INSTANCE: AppDatabase
fun getInstance(context: Context): AppDatabase {
if (!::INSTANCE.isInitialized) {
synchronized(AppDatabase::class) {
if (!::INSTANCE.isInitialized) {
INSTANCE = Room.databaseBuilder(context.applicationContext,
AppDatabase::class.java,
"app_database").build()
}
}
}
return INSTANCE
}
}
Call it with:
val db = DatabaseSource.getInstance(context)
And this will never be null
so you no longer have that issue.
I added double locking to be safer for thread safety on the getInstance()
call.
But really you should be using dependency injection with singletons to avoid this passed in dependency of context and this manual creation/locking. You'll have to have the context available everywhere which is a bad pattern.
This also acts as an answer to your other post which is apparently a duplicate of this one.
That indeed was what I am looking for. But how would I pass thecontext
here? Since I am creating INSTANCE in mycompanion object
, it's not a good practice to havecontext
inside static fields. Looking google sample, I see that they usealso
which works perfectly. What do you say?
– musooff
2 hours ago
Are you using dependency injection? because this seems like it should be injected as a singleton, and the context should be made available for injection as well.
– Jayson Minard
1 hour ago
1
The comment about not usinglateinit
there is not universally a valid comment. It is fine in any context where you KNOW the lifecycle gaurantees it will be instantiated before use. Here the only way to access it is by a method that guarantees it is valid. So you are fine. The other comment is not relevant without this context.
– Jayson Minard
1 hour ago
1
I saw your proposed edit of volatile, but since this is only modified under lock, and we are checking if assigned which is I believe a bit field that would not be partially set. You can add it if you want, but not sure it is really what you want and will just add more contention on accessing it.
– Jayson Minard
1 hour ago
1
Let's not add things we see in other posts without reason.
– Jayson Minard
1 hour ago
|
show 4 more comments
up vote
-1
down vote
In this code, you already check for the null
situation of your AppDatabase
instance:
if (INSTANCE == null){...}
Actually when you request an instance of your AppDatabase
then this above part will check that is there any instance of that available or not. And if you don't have any instance it will create a new instance for you then.
This class is a Singleton
class.
But before your first request to create an instance for AppDatabase
it's null
.
Hope this helped you.
Yeah indeedif (INSTANCE == null){...}
checks if not null then creates. My question was can it be still benull
while creating (insideif
). If it doesn't, then there is no need to haveAppDatabase?
as a return type ofgetInstance
Who my question was, if it's nevernull
then how can I instantiateAppDatabase
and havefun getInstance(context: Context) : AppDatabase{...}
– musooff
Nov 5 at 7:08
No, I mentioned that in my answer. When you try to get an instance of that you get an instance of that. But this class doesn't create an instance each time you want an instance for you and if there is an existing instance it will give it to you. otherwise, this class will create a new instance for you.
– Ehsan
Nov 5 at 7:13
Then how can I creategetInstance
method withAppDatabase
return type instead ofAppDatabse?
– musooff
Nov 5 at 7:15
add a comment |
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
1
down vote
accepted
Use something like this to make sure it is not null
object DatabaseSource {
private lateinit var INSTANCE: AppDatabase
fun getInstance(context: Context): AppDatabase {
if (!::INSTANCE.isInitialized) {
synchronized(AppDatabase::class) {
if (!::INSTANCE.isInitialized) {
INSTANCE = Room.databaseBuilder(context.applicationContext,
AppDatabase::class.java,
"app_database").build()
}
}
}
return INSTANCE
}
}
Call it with:
val db = DatabaseSource.getInstance(context)
And this will never be null
so you no longer have that issue.
I added double locking to be safer for thread safety on the getInstance()
call.
But really you should be using dependency injection with singletons to avoid this passed in dependency of context and this manual creation/locking. You'll have to have the context available everywhere which is a bad pattern.
This also acts as an answer to your other post which is apparently a duplicate of this one.
That indeed was what I am looking for. But how would I pass thecontext
here? Since I am creating INSTANCE in mycompanion object
, it's not a good practice to havecontext
inside static fields. Looking google sample, I see that they usealso
which works perfectly. What do you say?
– musooff
2 hours ago
Are you using dependency injection? because this seems like it should be injected as a singleton, and the context should be made available for injection as well.
– Jayson Minard
1 hour ago
1
The comment about not usinglateinit
there is not universally a valid comment. It is fine in any context where you KNOW the lifecycle gaurantees it will be instantiated before use. Here the only way to access it is by a method that guarantees it is valid. So you are fine. The other comment is not relevant without this context.
– Jayson Minard
1 hour ago
1
I saw your proposed edit of volatile, but since this is only modified under lock, and we are checking if assigned which is I believe a bit field that would not be partially set. You can add it if you want, but not sure it is really what you want and will just add more contention on accessing it.
– Jayson Minard
1 hour ago
1
Let's not add things we see in other posts without reason.
– Jayson Minard
1 hour ago
|
show 4 more comments
up vote
1
down vote
accepted
Use something like this to make sure it is not null
object DatabaseSource {
private lateinit var INSTANCE: AppDatabase
fun getInstance(context: Context): AppDatabase {
if (!::INSTANCE.isInitialized) {
synchronized(AppDatabase::class) {
if (!::INSTANCE.isInitialized) {
INSTANCE = Room.databaseBuilder(context.applicationContext,
AppDatabase::class.java,
"app_database").build()
}
}
}
return INSTANCE
}
}
Call it with:
val db = DatabaseSource.getInstance(context)
And this will never be null
so you no longer have that issue.
I added double locking to be safer for thread safety on the getInstance()
call.
But really you should be using dependency injection with singletons to avoid this passed in dependency of context and this manual creation/locking. You'll have to have the context available everywhere which is a bad pattern.
This also acts as an answer to your other post which is apparently a duplicate of this one.
That indeed was what I am looking for. But how would I pass thecontext
here? Since I am creating INSTANCE in mycompanion object
, it's not a good practice to havecontext
inside static fields. Looking google sample, I see that they usealso
which works perfectly. What do you say?
– musooff
2 hours ago
Are you using dependency injection? because this seems like it should be injected as a singleton, and the context should be made available for injection as well.
– Jayson Minard
1 hour ago
1
The comment about not usinglateinit
there is not universally a valid comment. It is fine in any context where you KNOW the lifecycle gaurantees it will be instantiated before use. Here the only way to access it is by a method that guarantees it is valid. So you are fine. The other comment is not relevant without this context.
– Jayson Minard
1 hour ago
1
I saw your proposed edit of volatile, but since this is only modified under lock, and we are checking if assigned which is I believe a bit field that would not be partially set. You can add it if you want, but not sure it is really what you want and will just add more contention on accessing it.
– Jayson Minard
1 hour ago
1
Let's not add things we see in other posts without reason.
– Jayson Minard
1 hour ago
|
show 4 more comments
up vote
1
down vote
accepted
up vote
1
down vote
accepted
Use something like this to make sure it is not null
object DatabaseSource {
private lateinit var INSTANCE: AppDatabase
fun getInstance(context: Context): AppDatabase {
if (!::INSTANCE.isInitialized) {
synchronized(AppDatabase::class) {
if (!::INSTANCE.isInitialized) {
INSTANCE = Room.databaseBuilder(context.applicationContext,
AppDatabase::class.java,
"app_database").build()
}
}
}
return INSTANCE
}
}
Call it with:
val db = DatabaseSource.getInstance(context)
And this will never be null
so you no longer have that issue.
I added double locking to be safer for thread safety on the getInstance()
call.
But really you should be using dependency injection with singletons to avoid this passed in dependency of context and this manual creation/locking. You'll have to have the context available everywhere which is a bad pattern.
This also acts as an answer to your other post which is apparently a duplicate of this one.
Use something like this to make sure it is not null
object DatabaseSource {
private lateinit var INSTANCE: AppDatabase
fun getInstance(context: Context): AppDatabase {
if (!::INSTANCE.isInitialized) {
synchronized(AppDatabase::class) {
if (!::INSTANCE.isInitialized) {
INSTANCE = Room.databaseBuilder(context.applicationContext,
AppDatabase::class.java,
"app_database").build()
}
}
}
return INSTANCE
}
}
Call it with:
val db = DatabaseSource.getInstance(context)
And this will never be null
so you no longer have that issue.
I added double locking to be safer for thread safety on the getInstance()
call.
But really you should be using dependency injection with singletons to avoid this passed in dependency of context and this manual creation/locking. You'll have to have the context available everywhere which is a bad pattern.
This also acts as an answer to your other post which is apparently a duplicate of this one.
edited 1 hour ago
answered 10 hours ago
Jayson Minard
35.5k13103170
35.5k13103170
That indeed was what I am looking for. But how would I pass thecontext
here? Since I am creating INSTANCE in mycompanion object
, it's not a good practice to havecontext
inside static fields. Looking google sample, I see that they usealso
which works perfectly. What do you say?
– musooff
2 hours ago
Are you using dependency injection? because this seems like it should be injected as a singleton, and the context should be made available for injection as well.
– Jayson Minard
1 hour ago
1
The comment about not usinglateinit
there is not universally a valid comment. It is fine in any context where you KNOW the lifecycle gaurantees it will be instantiated before use. Here the only way to access it is by a method that guarantees it is valid. So you are fine. The other comment is not relevant without this context.
– Jayson Minard
1 hour ago
1
I saw your proposed edit of volatile, but since this is only modified under lock, and we are checking if assigned which is I believe a bit field that would not be partially set. You can add it if you want, but not sure it is really what you want and will just add more contention on accessing it.
– Jayson Minard
1 hour ago
1
Let's not add things we see in other posts without reason.
– Jayson Minard
1 hour ago
|
show 4 more comments
That indeed was what I am looking for. But how would I pass thecontext
here? Since I am creating INSTANCE in mycompanion object
, it's not a good practice to havecontext
inside static fields. Looking google sample, I see that they usealso
which works perfectly. What do you say?
– musooff
2 hours ago
Are you using dependency injection? because this seems like it should be injected as a singleton, and the context should be made available for injection as well.
– Jayson Minard
1 hour ago
1
The comment about not usinglateinit
there is not universally a valid comment. It is fine in any context where you KNOW the lifecycle gaurantees it will be instantiated before use. Here the only way to access it is by a method that guarantees it is valid. So you are fine. The other comment is not relevant without this context.
– Jayson Minard
1 hour ago
1
I saw your proposed edit of volatile, but since this is only modified under lock, and we are checking if assigned which is I believe a bit field that would not be partially set. You can add it if you want, but not sure it is really what you want and will just add more contention on accessing it.
– Jayson Minard
1 hour ago
1
Let's not add things we see in other posts without reason.
– Jayson Minard
1 hour ago
That indeed was what I am looking for. But how would I pass the
context
here? Since I am creating INSTANCE in my companion object
, it's not a good practice to have context
inside static fields. Looking google sample, I see that they use also
which works perfectly. What do you say?– musooff
2 hours ago
That indeed was what I am looking for. But how would I pass the
context
here? Since I am creating INSTANCE in my companion object
, it's not a good practice to have context
inside static fields. Looking google sample, I see that they use also
which works perfectly. What do you say?– musooff
2 hours ago
Are you using dependency injection? because this seems like it should be injected as a singleton, and the context should be made available for injection as well.
– Jayson Minard
1 hour ago
Are you using dependency injection? because this seems like it should be injected as a singleton, and the context should be made available for injection as well.
– Jayson Minard
1 hour ago
1
1
The comment about not using
lateinit
there is not universally a valid comment. It is fine in any context where you KNOW the lifecycle gaurantees it will be instantiated before use. Here the only way to access it is by a method that guarantees it is valid. So you are fine. The other comment is not relevant without this context.– Jayson Minard
1 hour ago
The comment about not using
lateinit
there is not universally a valid comment. It is fine in any context where you KNOW the lifecycle gaurantees it will be instantiated before use. Here the only way to access it is by a method that guarantees it is valid. So you are fine. The other comment is not relevant without this context.– Jayson Minard
1 hour ago
1
1
I saw your proposed edit of volatile, but since this is only modified under lock, and we are checking if assigned which is I believe a bit field that would not be partially set. You can add it if you want, but not sure it is really what you want and will just add more contention on accessing it.
– Jayson Minard
1 hour ago
I saw your proposed edit of volatile, but since this is only modified under lock, and we are checking if assigned which is I believe a bit field that would not be partially set. You can add it if you want, but not sure it is really what you want and will just add more contention on accessing it.
– Jayson Minard
1 hour ago
1
1
Let's not add things we see in other posts without reason.
– Jayson Minard
1 hour ago
Let's not add things we see in other posts without reason.
– Jayson Minard
1 hour ago
|
show 4 more comments
up vote
-1
down vote
In this code, you already check for the null
situation of your AppDatabase
instance:
if (INSTANCE == null){...}
Actually when you request an instance of your AppDatabase
then this above part will check that is there any instance of that available or not. And if you don't have any instance it will create a new instance for you then.
This class is a Singleton
class.
But before your first request to create an instance for AppDatabase
it's null
.
Hope this helped you.
Yeah indeedif (INSTANCE == null){...}
checks if not null then creates. My question was can it be still benull
while creating (insideif
). If it doesn't, then there is no need to haveAppDatabase?
as a return type ofgetInstance
Who my question was, if it's nevernull
then how can I instantiateAppDatabase
and havefun getInstance(context: Context) : AppDatabase{...}
– musooff
Nov 5 at 7:08
No, I mentioned that in my answer. When you try to get an instance of that you get an instance of that. But this class doesn't create an instance each time you want an instance for you and if there is an existing instance it will give it to you. otherwise, this class will create a new instance for you.
– Ehsan
Nov 5 at 7:13
Then how can I creategetInstance
method withAppDatabase
return type instead ofAppDatabse?
– musooff
Nov 5 at 7:15
add a comment |
up vote
-1
down vote
In this code, you already check for the null
situation of your AppDatabase
instance:
if (INSTANCE == null){...}
Actually when you request an instance of your AppDatabase
then this above part will check that is there any instance of that available or not. And if you don't have any instance it will create a new instance for you then.
This class is a Singleton
class.
But before your first request to create an instance for AppDatabase
it's null
.
Hope this helped you.
Yeah indeedif (INSTANCE == null){...}
checks if not null then creates. My question was can it be still benull
while creating (insideif
). If it doesn't, then there is no need to haveAppDatabase?
as a return type ofgetInstance
Who my question was, if it's nevernull
then how can I instantiateAppDatabase
and havefun getInstance(context: Context) : AppDatabase{...}
– musooff
Nov 5 at 7:08
No, I mentioned that in my answer. When you try to get an instance of that you get an instance of that. But this class doesn't create an instance each time you want an instance for you and if there is an existing instance it will give it to you. otherwise, this class will create a new instance for you.
– Ehsan
Nov 5 at 7:13
Then how can I creategetInstance
method withAppDatabase
return type instead ofAppDatabse?
– musooff
Nov 5 at 7:15
add a comment |
up vote
-1
down vote
up vote
-1
down vote
In this code, you already check for the null
situation of your AppDatabase
instance:
if (INSTANCE == null){...}
Actually when you request an instance of your AppDatabase
then this above part will check that is there any instance of that available or not. And if you don't have any instance it will create a new instance for you then.
This class is a Singleton
class.
But before your first request to create an instance for AppDatabase
it's null
.
Hope this helped you.
In this code, you already check for the null
situation of your AppDatabase
instance:
if (INSTANCE == null){...}
Actually when you request an instance of your AppDatabase
then this above part will check that is there any instance of that available or not. And if you don't have any instance it will create a new instance for you then.
This class is a Singleton
class.
But before your first request to create an instance for AppDatabase
it's null
.
Hope this helped you.
answered Nov 5 at 7:00
Ehsan
399522
399522
Yeah indeedif (INSTANCE == null){...}
checks if not null then creates. My question was can it be still benull
while creating (insideif
). If it doesn't, then there is no need to haveAppDatabase?
as a return type ofgetInstance
Who my question was, if it's nevernull
then how can I instantiateAppDatabase
and havefun getInstance(context: Context) : AppDatabase{...}
– musooff
Nov 5 at 7:08
No, I mentioned that in my answer. When you try to get an instance of that you get an instance of that. But this class doesn't create an instance each time you want an instance for you and if there is an existing instance it will give it to you. otherwise, this class will create a new instance for you.
– Ehsan
Nov 5 at 7:13
Then how can I creategetInstance
method withAppDatabase
return type instead ofAppDatabse?
– musooff
Nov 5 at 7:15
add a comment |
Yeah indeedif (INSTANCE == null){...}
checks if not null then creates. My question was can it be still benull
while creating (insideif
). If it doesn't, then there is no need to haveAppDatabase?
as a return type ofgetInstance
Who my question was, if it's nevernull
then how can I instantiateAppDatabase
and havefun getInstance(context: Context) : AppDatabase{...}
– musooff
Nov 5 at 7:08
No, I mentioned that in my answer. When you try to get an instance of that you get an instance of that. But this class doesn't create an instance each time you want an instance for you and if there is an existing instance it will give it to you. otherwise, this class will create a new instance for you.
– Ehsan
Nov 5 at 7:13
Then how can I creategetInstance
method withAppDatabase
return type instead ofAppDatabse?
– musooff
Nov 5 at 7:15
Yeah indeed
if (INSTANCE == null){...}
checks if not null then creates. My question was can it be still be null
while creating (inside if
). If it doesn't, then there is no need to have AppDatabase?
as a return type of getInstance
Who my question was, if it's never null
then how can I instantiate AppDatabase
and have fun getInstance(context: Context) : AppDatabase{...}
– musooff
Nov 5 at 7:08
Yeah indeed
if (INSTANCE == null){...}
checks if not null then creates. My question was can it be still be null
while creating (inside if
). If it doesn't, then there is no need to have AppDatabase?
as a return type of getInstance
Who my question was, if it's never null
then how can I instantiate AppDatabase
and have fun getInstance(context: Context) : AppDatabase{...}
– musooff
Nov 5 at 7:08
No, I mentioned that in my answer. When you try to get an instance of that you get an instance of that. But this class doesn't create an instance each time you want an instance for you and if there is an existing instance it will give it to you. otherwise, this class will create a new instance for you.
– Ehsan
Nov 5 at 7:13
No, I mentioned that in my answer. When you try to get an instance of that you get an instance of that. But this class doesn't create an instance each time you want an instance for you and if there is an existing instance it will give it to you. otherwise, this class will create a new instance for you.
– Ehsan
Nov 5 at 7:13
Then how can I create
getInstance
method with AppDatabase
return type instead of AppDatabse?
– musooff
Nov 5 at 7:15
Then how can I create
getInstance
method with AppDatabase
return type instead of AppDatabse?
– musooff
Nov 5 at 7:15
add a comment |
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53149350%2fcan-anytime-appdatabase-in-android-room-be-null%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown