I have a SQLiteOpenHelper that wraps my Database. the SQLiteOpenHelper subclass is implemented as Singleton to avoid MultiTread problems and it seems to work quite well.
The problem is: testing classes that uses the database.
In AndroidTestCase i want to test methods that depends on DB in isolation so i use
setContext(new RenamingDelegatingContext(getContext(), "test_"));
and than use the IsolatedContext to get a separate empty instance of the db.
So, the android app need the singleton but Junit need a simple instance.
The only approach i found at the moment is declare SQLiteOpenHelper subclass with two contructors , one static that return the singleton instance and another that return a new instance . Than add to every class that use the db add one constructor to use the singleton an other that use a new instance.
This approach it is very ugly and error prone , so there is a more logical elegant way to do so?
(ps i'm not using ContentProvider and not interested in so please do not suggest them as solution)
Related
Currently, I have a database manager class that handles all operations to the database like this:
class DatabaseManager(val context: Context) {
private val db = Firebase.firestore
//Other functions, etc.
}
It makes use of the context passed in by different activities to perform functions to the database. The thing is, every single activity that requires database functions have to instantiate this manager class first, then call the functions. I would like to make use of the Singelton design pattern to make it such that all the activities will only use a single instance of the class. I believe kotlin's objects can do this, however I also need to be able to pass in the context of the activities into this manager class. Any assistance is appreciated, thank you!
I would recommend not doing that. The problem with Singletons is that they make code hard to test, you can't fake out the database. And for a database this is a particularly bad problem, as setting up all the right fake data can be painful. Instead, take a look at injection. It can do the same thing (make a single instance shared between everyone who needs it), but it manages that global state rather than having the classes themselves manage it via a static reference, passing it in (generally via the constructor) to whoever needs it. This makes it easy to provide an alternative or mock database when needed for testing. Injection used to be a bit painful to set up, but Hilt makes it a lot easier these days.
I created a custom Application class for my app. This class onCreate sets a static variable of itself like this
public void onCreate() {
super.onCreate();
mInstance = this;
}
public static ChattyApp getInstance() {
return mInstance;
}
Then I use App.getInstance() method to get application context to a nonactivity/fragment class like API Controller or something. Can it cause a memory leak?
I setup leak canary and it is showing memory leak on an instance variable of Application class. This variable keeps socket.io's socket ref so that I can use it anywhere in the app.
It is a good question that you have asked and people on SO have had extensive discussions on this. Have a look at this and this
Although this seems to be an okay way to store the Context in Application class as per the discussion in the first link, there can be better ways to deal with this.
Ideally for each logic unit you should have a separate class to deal with it rather than polluting your application class. You application class can however initialize or setup those other classes. This will create a separation of concern.
Another way is to use Dagger2, which is a dependency injection framework, to inject your socket ref to wherever you want.
Dagger 2 has a steep learning curve and but a very important tool to learn as an Android developer
I have created an application which uses a lot of custom objects I've created to manage parts of the application.
for example:
FacebookManager class - responsible for connecting to facebook
DatabaseManager class - responsible for application's database connection
etc...
these classes must be reachable for all application's classes.
i've extend the Application class and i'm sharing the Application instance between class so every class will be able to reach the global objects (and some more methods).
i'm wondering if this is the correct way of doing what i want, or should i create a class with static methods for the same propose.
I've read a lot about it and understood that from the memory point of view - non of these ways are best.
is there a way to save an object to the SharedPereferences and get it from another class ?
or any other idea ?
If your classes contain no states but only utility methods - you can arrange them as Utils classes, with no constructors and static methods. Otherwise, take a look at the Singleton design pattern, which is used to create a global access point for an object of class and ensures there's only one object of that class in the whole system. Hope this helps.
How can i open a database in a class that is not a subclass of Activity?
In a subclass of Activity, i can use openOrCreateDatabase() but can i open a database in a different class?
I tried making the database instance a static one and open it in an Activity and get the static instance in the other class, but it throws an exception stating the database is closed.
Check out this tutorial.
I went through it and it's a really good tutorial on how to use SQLite in Android.
Essentially you need to create a database helper class that will do the table creation. Then you can use this helper class in your Activity to create your database and or tables.
It's common practice to use a SQLite Database Adapter and sometimes a helper class that is separate from the activity that is utilizing the database. Here is a link to a example that uses the code. THe vogella tutorial is also good but the use of a ContentProvider makes it a bit tough to understand what things need to be in there for a SQLite DB only.
Essentially, the helper class is responsible for creating, updating and deleting the DB while the adapter class handles the methods for changing values, deleting rows, and actually calling the helper to open the database.
There are many questions and answers on how to implement a global variable in Android/Java.
So it seems one can either implement a singleton or use a data class itself with static variables.
I am about to start a larger project and would like to start on the right foot.
I am just not sure which one to use.
Pro singleton/con Data Class
supposedly "cleaner" way (but I really don't know why)
ensures that there is really always just one representation
creates a new instance should the old one be "cleaned away" (whenever this may happen?)
Con singleton/pro Data Class
not recommendet by some (but did not find convincng reasons)
ensures that there is only one representation by design
very easy to access just by writing MyDataClass.x (vs accessing singleton requires getting access to it first somehow)
no need to pass it as a parameter
So in summary I tend to use DataClass but I am unsure because I read that this is supposedly not good programming style.
I like to add
the data this global object has to hold is quite big, more than 30k strings/keys. And this should not be cleaned at any stage so that when the app return it may crash because of that - as I read in other places eg Singletons vs. Application Context in Android? (the 3rd answer)
it's not a web application, I use only one classloader
it is multithread but only one thread is actually accessing this data
one may certainly also use this approach How to declare global variables in Android?, but isn't an ObjectClass just easier to use and access in this case?
And checking this http://developer.android.com/resources/faq/framework.html, esp under "Persistent Objects", implies that there is no real advantage for on or the other in those cases anyway.
Many thanks
Best way to implement singleton is to use enum.
public enum Singleton
{
INSTANCE;
public void someMethod()
{
// your code here
}
}
For more details you can read Effective Java (2nd Edition)
First of all: There's not much difference between a class with public static member variables and a singleton class. A lot of developers prefer the singleton pattern because the code looks more natural and more Java. E.g. Singleton.Data looks like a constant access and Singleton.getData() looks like you're accessing some kind of static data.
Personally I use the static Application pattern: See Accessing resources without an Activity or Context reference
You can use onCreate to setup any kind of static data or even other singletons. E.g. I prefer to setup a singleton SQLite database like that and access it then via App.getDb(). You can use this pattern to access the application context or resources.
While using static data you should think about memory leeks. I would recommend to take a look at this article then.