Using static variables in Android
Asked Answered
K

5

61

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?

Kristy answered 19/3, 2010 at 8:51 Comment(1)
I believe you will need a lock for synchronization for your singleton class, otherwise, you are going to have multiple objects on heap memory under multi-thread scenario.Teller
O
66

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.

Osteoclasis answered 19/3, 2010 at 9:30 Comment(9)
Confirmed, it'll be retained until your entire process is destroyed. When your process is revived, your singleton will reappear!Pricket
It should be noted that the singleton will be recreated, but the original state of the singleton is not automaticaly restored. This would have to be done manually.Persas
@Kevin Can you elaborate your comment?Lapwing
@harshjv Singletons are often designed to be immutable too, in which case it doesn't matter whether you see an old or new copy of it. But if your singleton maintains state, that state is lost when the singleton is destroyed. It gets recreated, but with default initial state.Osteoclasis
@harshjv, Sean Owen is correct. When the process is destroyed, the singleton is destroyed. When the process is revived the singleton will be recreated automatically. However any properties or underlying private member variables of the singleton will not be restored automatically. You must put in the work to save and restore the state of the object separately.Persas
I have tested this and I beg for differ, It is possible to free up the allocated memory by setting the static variable to null.Mafala
I don't believe anyone suggested otherwise. The question is whether the pattern makes sense and how it behaves.Osteoclasis
@KevinWestwood I do not understand what you meant by singleton will be recreated, but the original state of the singleton is not automaticaly restored. I created a list of String s and it was restored just fine. What do you mean by original state ?Dincolo
If your code initializes the singleton to have some state like your list of strings, then of course it will have that every time it is created. If your code somehow changes that state like adds to the list, then no those will not be recreated. This is the same as every other object in the JVM.Osteoclasis
P
15

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.

Path answered 3/9, 2010 at 20:0 Comment(6)
Binding, Callbacks/Listeners, but not staticPep
Have you heard about intents? static fields are bad practice, it tends to tightly couple ...Gummous
Can you please guys provide proper solution for me? With static variables I'm facing a problem when app comes from background or stays open for many hours, it crashes. With intent it is very hard to pass objects. So what is the proper way to do this?Disinherit
@SagarPanwala try using Parcelables. If you have large bitmaps that are making huge impact on your memory try using a proper library for it like Picasso.Scoggins
@SagarPanwala can you provide more details on the crash?Whap
@SIrCodealot: App is crashing when I make it open and didn't touch for 1 day or so. Even if I backgrounded the app for many hours or open to many applications and trying to open my app , it is crashing. There might be many problems, but I figure out one and that is static variable got null after sometime or memory usage. I'm already using Picasso.Disinherit
D
1

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.

Din answered 23/3, 2019 at 1:31 Comment(0)
B
0

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.

Bonanza answered 19/3, 2010 at 9:26 Comment(1)
I don't think that this might actually be a problem since the DVM manages it's memory pretty well.Shakeup
A
-7

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.

Agricola answered 19/3, 2010 at 9:31 Comment(6)
Bear in mind that the core Android team advocates the use of your "anti-pattern", and that Google Guice appears to require about 800KB of JARs, which is bad for a mobile app.Venous
Guice is great, but it might be overkill for many applications. But if you are going to dive into Guice, take a look at this fine project: code.google.com/p/roboguicePricket
Dependency injection stuff brings complexity. I have seen some developers spending hours finding out why the wrong objects got injected. Singleton has its values!Drizzle
@Drizzle frameworks do bring complexity, but one can also perform explicit injection (without a framework), which is quite understandable. Both, however, are still better than using a singleton, which makes code inflexible and difficult to test. See my link for my justification for why singleton is an anti-pattern and is to be avoided.Agricola
Your view of a singleton pattern here makes the brittle assumption that use of a private constructor causes a single instance. This is not the case. The single instance is policy and not language enforced in the implementation of the static object instance creation method, eg: "getInstance". You can have this method return as many instances as you like or one, depending on what you intend for the class.Yea
Google member also recommends to avoid singletons : testing.googleblog.com/2008/05/… @Venous can you please share your thoughts. This is quite debatable and a lot of developers like me get confused on what's the right approach.Clod

© 2022 - 2024 — McMap. All rights reserved.