Behavior of static class variables in Android application [duplicate] - java

In android, are using static variables a recommended practice?
E.g, implementing a Singleton pattern in Java, I usually do:
private static A the_instance;
public static A getInstance() {
if (the_instance == null) {
the_instance = new A();
}
return the_instance;
}
Also, when does this get cleaned up by the Android JVM?

static fields are attached to the Class instance as a whole, which is in turn attached to the ClassLoader which loaded the class. the_instance would be unloaded when the entire ClassLoader is reclaimed. I am 90% sure this happens when Android destroys the app (not when it goes into the background, or pauses, but is completely shut down.)
So, think of it as living as long as your app runs. Is Singleton a good idea? People have different views. I think it's fine when used appropriately, myself. I don't think the answer changes much on Android. Memory usage isn't the issue per se; if you need to load a bunch of stuff in memory, that's either a problem or it isn't, regardless of whether you encapsulate the data in a Singleton.

I think static variables are OK.
This is what Android doc says:
http://developer.android.com/guide/appendix/faq/framework.html
How do I pass data between Activities/Services within a single application?
A public static field/method
An alternate way to make data accessible across Activities/Services is to use public static fields and/or methods. You can access these static fields from any other class in your application. To share an object, the activity which creates your object sets a static field to point to this object and any other activity that wants to use this object just accesses this static field.

Contrary to what other people say - it is more than ok. Granted, it has some structure to it. In the official googlesamples/android-architecture repo it is used under todo-mvp-clean (Todo app implementing MVP pattern and following Clean Architecture principles).
Check out this file.
What you can see is a lot of static methods referencing singleton getters.
Modern, less error prone and convenient alternative is the Dagger DI framework.

I'm not sure if such approach is good for mobile platform where you have limited memory available to you. Not to mention that the application will be run on a multi-tasking enabled device.
I think, this approach may hog memory from the device but I have no document to support this. Perhaps someone who's more educated than me can share their thoughts.

No. Don't do it! Singleton is an anti-patern!. Instead, use dependency injection, whether via a framework (such as via Dagger or Roboguice) or by explicitly passing the instantiated object.

Related

How to maintain a centralized Object across the application

I am developing an application where I need to create an object and multiple classes have to access and modify that object. How to see the recent changes made by the other class object and how to access the object centrally through all the classes with out passing that object as a parameter across all the classes?
I am creating an Apache POI document where I am adding multiple tables, multiple headers/footers and paragraphs. I want only a single XWPFDocument object present in my application.
Is there any design pattern we can achieve this?
Well the singleton design pattern would work - but isn't terribly clean; you end up with global static state which is hard to keep track of and hard to test. It's often considered an anti-pattern these days. There are a very few cases where it still makes sense, but I try to avoid it.
A better approach would be to use dependency injection: make each class which needs one of these objects declare a constructor parameter of that type (or possibly have a settable property). Each class shouldn't care too much about how shared or otherwise the object is (beyond being aware that it can be shared). Then it's up to the code which initializes the application to decide which objects should be shared.
There are various dependency injection frameworks available for Java, including Guice and Spring. The idea of these frameworks is to automatically wire up all the dependencies in your application, given appropriate configuration.
There is Singleton Pattern for this, it creates a single instance for the application and is shared without passing around.
But it not not the best of options.
Why is it a bad option?
It is not good for testability of code
Not extensible in design
Better than Singleton Pattern is an application wide single instance
Create a single object for the application and share it using some context object. More on this is explained by Misko in his guide to testable code
single instance and not Singleton Pattern
It stands for an application wide single instance, which DOES NOT inforce its singletonness through a static instance field.
Why are Singletons hard to test?
Static access prevents collaborating with a subclass or wrapped version of another class. By hard-coding the dependency, we lose the power and flexibility of polymorphism.
-Every test using global state needs it to start in an expected state, or the test will fail. But another object might have mutated that global state in a previous test.
Global state often prevents tests from being able to run in parallel, which forces test suites to run slower.
If you add a new test (which doesn’t clean up global state) and it runs in the middle of the suite, another test may fail that runs after it.
Singletons enforcing their own “Singletonness” end up cheating.
You’ll often see mutator methods such as reset() or setForTest(…) on so-called singletons, because you’ll need to change the instance during tests. If you forget to reset the Singleton after a test, a later use will use the stale underlying instance and may fail in a way that’s difficult to debug.

when is a singleton class preferred over a class that has only static methods?

When is a singleton class preferred over a class that has only static methods and a private default constructor?
Please vote.
Use a singleton to better control when initialization occurs. With a static class, any initialization must be at class load-time, which you have little control over. For example, a simple reference to a static final MEMBER will trigger class loading. With a singleton, initialization can trivially be deferred till much later - typically, till first time of use.
Reasons to delay initialization may be:
it's expensive and you don't always need it for that class
you can't initialize till some other resource is initialized (say, a database connection). In this case, a lazily-instantiated singleton often provides correct order of operations without any explicit control - if it's not referenced till after the other resource is initialized, everything happens for free.
Use a singleton to improve testability. If you need to make some kind of mock object (in the broad sense) of the singleton in order to test its clients, one way to do it is to put an interface on its use, and supply a test singleton that's of a different class but implements the same interface.
Using a singleton makes initialization testing easier as well.
Use a singleton when you might need to debug initialization. Stack traces from static initialization can be puzzling. Debugging can be puzzling too. If the class is loaded early, it may break before a breakpoint on the first line in main() is even hit.
When is a singleton class preferred over a class that has only static methods and a private default constructor?
When you need an instance. For example, to pass as method argument.
The main reason for only having static methods is when you just need a toolbox to pack some functions together.
I use singletons for mainly two reasons:
It is really expensive (time or memory) to construct the object, and
I want to only ever do it once.
The data associated with the class
needs to be the same in every instance of the class.
If you have some state you need to store, a singleton is the way to go. For instance, if your class needs to load some configuration from a properties file.
Static method is not dynamic, this is a big different with singleton class instance. So if you need to extends from a class and override some method, the second way won't work.
And the for the second way, you may need to use some static references which may lead to memory leak.
I would say that a singleton class would be preferred only in one case: when you have some configuration to store that is system wide, will rarely (if ever) need to be refreshed.
As an example of what I mean, I have a singleton pattern in one of my applications that represents the NAT device of the user's internet connection. This application is intended for desktop use, and so would rarely (if ever) see a change in the internet connection. Presumably the user could carry their laptop to a new location, and this would change; however, there is a method to recreate the state in this event, but this is very infrequently changed state that can take several seconds to initialize.
This need to keep expensive, infrequently changing, and globally applicable state is best done by either an application scoped bean (my preferred option) or a singleton pattern bean. Static methods aren't as good for preserving this kind of state, though you could also accomplish this using static fields as well to make a pseudo-singleton. (Not sure if there's a better name for this - probably)
In general, my recommendation is not to use singleton like patterns if you can avoid it, as it makes re-use more difficult. If you're using a CDI framework, scope your bean at the application level for easier re-use. (This may not be a concern of yours - if not, you may safely ignore this advice)

Where exactly the Singleton Pattern is used in real application?

I was just curious where exactly the singleton pattern is used...
I know how the pattern works and where it can be used but i personally never used in any real application.
Can some one give an example where it can be used..
I would really appreciate if some one can explain how and where they have used in real application.
Thanks,
Swati
Typically singletons are used for global configuration. The simplest example would be LogManager - there's a static LogManager.getLogManager() method, and a single global instance is used.
In fact this isn't a "true" singleton as you can derive your own class from LogManager and create extra instances that way - but it's typically used as a singleton.
Another example would be java.lang.Runtime - from the docs:
Every Java application has a single
instance of class Runtime that allows
the application to interface with the
environment in which the application
is running. The current runtime can be
obtained from the getRuntime method.
That's pretty much the definition of a singleton :)
Now the singleton pattern is mostly frowned upon these days - it introduces tight coupling, and makes things which use the singleton harder to test, as you can't easily mock out that component. If you can get away without it, so much the better. Inject your dependencies where possible instead.
Some examples:
Hardware access
Database connections
Config files
I used the singleton pattern in an online Football Team Store System. we applied the singleton pattern to a ShoppingCart class.
You only needed one instance of the cart per an application instance. so the singleton seemed like it's the best fit for that situation.
Consider the situation of AudioDriverService which is designed in Singleton Pattern. So we are allowed to create just a single instance of AudioDriverService class. Now actually your Windows Media Player or Youtube Player both will share the same object of AudioDriverService rather than creating a new instance.
When you use Logger, you use Singleton pattern for the Logger class. In case it is not Singleton, every client will have its own Logger object and there will be concurrent access on the Logger instance in Multithreaded environment, and multiple clients will create/write to the Log file concurrently, this leads to data corruption.
For example running a trial version of a software with one license and one database connection ,that uses singleton pattern in real word. may be the guru jon skeet can provide example like this.
Singleton pattern is generally useful when the object that is created once and shared
across different threads/Applications.
Consider the case that you are implementing the properties load class for a printer.
Now Printers can be of variant properties. For eg:-
Mono Printer,
Color Printer,
Automatic Scanner Support Printer and so on...
Every time on boot this config file has to load to enable a few buttons/ applications
on the UI say tab or any Printer UI.
The value of the supported features are stored in form of a config table like say 1 if
feature supported and 0 if not supported.
Based on the supported features we enable disable certain functionalities and application
on the UI. Now this config file location in case of printers manufactured by a single company
are always stored at a fixed path.
The file values would change/would be read only in the following scenarios:-
1. On Boot.
2. on Addition or deletion of any new hardware peripheral.
We can use a singleton class to implement the reading of configuration files. As the same values
i.e. the config does not change on UI intervention and can be changed only on hardware intervention.
This is one example I can think of where we can implement Singleton design pattern.
Singleton is a nice design pattern. Before deciding on the pattern first do an in depth analysis of your problem and the solution. If in your solution some object has only one instance and you want to model that in your design then you should use singleton pattern. For example if you are modelling a PC in the software there can be only one instance of a PC with respect to your running program. As Jon Skeet said java.lang.Runtime is modelled as a singleton because for all the java objects that are loaded and running inside a java runtime there is only one instance of runtime.
Again lot of times it is used for the wrong reasons. Never create a singleton so that you can easily access the object (like Object::instance() ) from anywhere without passing the object around. The is the worst use I have ever come across.
I use a media player in my android app, so I extend the mediaplayer class, and used the singleton pattern because I need only one instance, and be able to call the same instance in any other part of my app for check if is playing, or what file is current playing.
Hope it helps you, regards!!!!
Singleton Pattern can be used for loading the configuration , say in a web application, we are supposed to generate a file which is to be stored somewhere in the server. Now, that location can fetched from a config file(properties file) using a singleton class.since the location is to be unique and might change frequently in future, so we use a config file so as can be modified without deploying the application so as to reflect the changes and location will be global and unique through out the application
I used a singleton (actually a couple of them) in an application that used pureMVC. We were unhappy about the complexity this framework introduced (it became complicated and tiering to track method calls through the mvc layers). So we used a central singleton as a mediator to better separate the layers from each other.
Singleton Class is basically used when you have to allow only single instantiation of the class.
Taking real world example, In case of OOP designing of a library, we can create library class as singleton class.

Using static variables in Android

In android, are using static variables a recommended practice?
E.g, implementing a Singleton pattern in Java, I usually do:
private static A the_instance;
public static A getInstance() {
if (the_instance == null) {
the_instance = new A();
}
return the_instance;
}
Also, when does this get cleaned up by the Android JVM?
static fields are attached to the Class instance as a whole, which is in turn attached to the ClassLoader which loaded the class. the_instance would be unloaded when the entire ClassLoader is reclaimed. I am 90% sure this happens when Android destroys the app (not when it goes into the background, or pauses, but is completely shut down.)
So, think of it as living as long as your app runs. Is Singleton a good idea? People have different views. I think it's fine when used appropriately, myself. I don't think the answer changes much on Android. Memory usage isn't the issue per se; if you need to load a bunch of stuff in memory, that's either a problem or it isn't, regardless of whether you encapsulate the data in a Singleton.
I think static variables are OK.
This is what Android doc says:
http://developer.android.com/guide/appendix/faq/framework.html
How do I pass data between Activities/Services within a single application?
A public static field/method
An alternate way to make data accessible across Activities/Services is to use public static fields and/or methods. You can access these static fields from any other class in your application. To share an object, the activity which creates your object sets a static field to point to this object and any other activity that wants to use this object just accesses this static field.
Contrary to what other people say - it is more than ok. Granted, it has some structure to it. In the official googlesamples/android-architecture repo it is used under todo-mvp-clean (Todo app implementing MVP pattern and following Clean Architecture principles).
Check out this file.
What you can see is a lot of static methods referencing singleton getters.
Modern, less error prone and convenient alternative is the Dagger DI framework.
I'm not sure if such approach is good for mobile platform where you have limited memory available to you. Not to mention that the application will be run on a multi-tasking enabled device.
I think, this approach may hog memory from the device but I have no document to support this. Perhaps someone who's more educated than me can share their thoughts.
No. Don't do it! Singleton is an anti-patern!. Instead, use dependency injection, whether via a framework (such as via Dagger or Roboguice) or by explicitly passing the instantiated object.

Problem with static attributes

My problem is that I'm working on a project that requires me to run multiple instances of someone elses code which has many static attributes/variables, which causes all the instances to share those resources and, well, crash. I can run multiple instances of this other person's program if I create a .jar file off of it and open it multiple times by running the .jar in windows, but running calling the "main" method multiple times in my code (which is what I need to do) won't work.
I thought about creating a .jar and using Runtime.getRuntime().exec( "myprog.jar" ); to call the program multiple times, but that won't work for me since I have to pass an instance of my object to this new program and I don't think this solution would allow for that.
PS: This is also posted in the Sun forums, so I`ll post the answer I get there here or the answer I get here there naturally giving proper credit once I this is solved =P.
Remember that a static element in Java is unique only in the context of a classloader (hierarchy); a class is uniquely identified in a JVM by the tuple {classloader, classname}.
You need to instantiate isolated classloaders and load the jar using that class loader. Each loaded class (and thus statis elements) are unique in their classloader and will not interfere with one another.
I'd say you have three alternatives:
Refactor the legacy application so that it doesn't use static attributes. If you can do this, this may be the best solution in the long term.
Continue with your approach of launching the legacy application in a separate JVM. There are a number of ways that you can pass (copies of) objects to another JVM. For example, you could serialize them and pass them via the child processes input stream. Or you could stringify them and pass them as arguments. In either case, you'll need to create your own 'main' class/method that deals with the object passing before calling the legacy app.
I think you should be able to use classloader magic to dynamically load a fresh copy of the legacy application each time you run it. If you create a new classloader each time, you should get a fresh copy of the legacy application classes with a separate set of statics. But, you have to make sure that the legacy app is not on your main classpath. The problem with this approach is that it is expensive, and you are likely to create memory leaks.
The description is a little confusing.
If you are running the code multiple times, you are running multiple independent processes, each running in its own JVM. There is no way that they are actually sharing the values of their static fields. Java doesn't let you directly share memory between multiple VMs.
Can you elaborate more (ideally with examples and code) what the attributes are defined as and what kind of failures you are getting? This may be completely unrelated to them being static.
In particular, what exactly do you mean by shared resources? What resources are your programs sharing?
The proper approach was already suggested - using custom ClassLoaders. Another thing comes to my mind, which might seem ugly, but will probably do, and is a bit more object-oriented approach.
The legacy code is used for its operations, and it incorrectly uses static instead of instance variables. You can fix that using inheritance and reflection:
create (or reuse) an utility class that copies instance variables to static ones
extend the classes in question and provide the same instance variables as the static ones
override all methods. In the overriding methods use the utility to copy the state of the current object to the static variables, and then delegate to (call) the super methods.
Then start using instance of your class, instead of the legacy ones. That way you will simulate the proper behaviour.
Have in mind this is NOT thread-safe.

Categories