2

I got a singleton class in my application, which is defined just somewhat like:

public class SingletonTest {
    private SingletonTest() {}

    private static SingletonTest instance = new SingletonTest();

    public static SingletonTest getInstance() {
        return instance;
    }
}

When I exit my application and open again, the instance has not been initialized again because the former one is not destroyed and still in JVM. But what I want is to initialize the static field every time I enter my application. So, what should I do in the onDestroy() method? Thanks a lot!

Iswanto San
  • 18,263
  • 13
  • 58
  • 79
Judking
  • 6,111
  • 11
  • 55
  • 84
  • 1
    Create `SinggletonTest.init()` and call it from the app `Activity` `onStart()` or similar over-ridden method. – donfede Apr 14 '13 at 03:27
  • 1
    Singletons are highly discouraged. If you want a single instance of a class in your application I recommend dependency injection, and when you bind your class tell it to bind as a singleton. This gets rid of the static reference, and gives you the behavior you want. – Christopher Perry Apr 14 '13 at 03:53
  • @ChristopherPerry While I'm not a big fan of overuse of singletons, to say they're highly discouraged is a bit of a stretch. At least one prominent developer on the Android team recommends using them: http://stackoverflow.com/questions/3826905/singletons-vs-application-context-in-android – kabuko Apr 14 '13 at 05:55
  • @kabuko, I disagree with Dianne Hackborn, same as the answer in your link, and for the very same reasons. – Christopher Perry Apr 14 '13 at 07:07
  • 1
    @ChristopherPerry Thanks for advise! Could you recommend a `dependency injection` framework which is suitable and popular for `android` project? – Judking Apr 14 '13 at 11:02
  • @Judking, sure there are two: [Roboguice](https://code.google.com/p/roboguice/) and [Dagger](http://square.github.io/dagger/). I suggest going with Dagger, since it doesn't use reflection. However, if performance isn't a concern Roboguice is nice, and you can inject on an interface. – Christopher Perry Apr 15 '13 at 22:43

2 Answers2

3

Your static variable will remain in memory as long as your application stays in memory. This means that, a static variable will be automatically destroyed together with your app.

If you want a new instance of your singleton, you will need to create a static method that reinitializes your singleton and call it in the onStart of your application object or the first activity you launch(or whenever you need it)

private Singleton() {}
private static Singleton mInstance;

//use this method when you want the reference
public static Singleton getInstance() {
    //initializing your singleton if it is null
    //is a good thing to do in getInstance because
    //now you can see if your singleton is actually being reinitialized.
    //e.g. after the application startup. Makes debugging it a bit easier. 
    if(mInstance == null) mInstance = new Singleton();

    return mInstance;
}

//and this one if you want a new instance
public static Singleton init() {
    mInstance = new Singleton();
    return mInstance;
}

something like that should do.

Joey Roosing
  • 2,145
  • 5
  • 25
  • 42
  • As you said: **a static variable will be automatically destroyed together with your app**. Why doesn't the static field destroy since my app has been destroyed? Why can't the `singleton class` be unloaded together with my app's destruction? Thanks. – Judking Apr 14 '13 at 03:41
  • 2
    If your application is compeletely removed from memory it should also delete the static variable from memory. Are you sure your application is completely destroyed? have you for example in the application settings force closed it, then reopen it with a breakpoint in your singleton to see if it is null and will be reinitialized? Also how do you define wether its that same instance or a new one? since you leave instantiating to the class loader it will pretty much always be instantiated when ever you first call your singleton. See my comments in getInstance() – Joey Roosing Apr 14 '13 at 03:44
1

From what you are saying, it seems that Singleton is not suited for what you want to do. You should declare an instance variable that would be initialized/cleared by the methods onCreate()/onStart() and onStop()/onDestroy().

See this graph for the Activity lifecycle.

Source : http://developer.android.com/reference/android/app/Activity.html

Pierre Laporte
  • 1,205
  • 8
  • 11