1

I'm writing an Android app currently and I have a higher level question about when to use a static method/field.

My app tracks time usage across different activities, each activity is an instance of a class. I need a method that can return all instances of this class.

Is it bad design to place a static method/field in my Activity class like so:

static ArrayList<Activity> allInstances;    
public static void addToComprehensiveList(Activity a) {
    if(allInstances == null)
        allInstances = new ArrayList<Activity>();
    allInstances.add(a);
}
public static ArrayList<Activity> getComprehensiveList() {
    return allInstances;
}

What's the correct design choice here?

ALSpringer
  • 55
  • 1
  • 4
  • 1
    Look at the Singleton pattern. This design probably isn't the best way to do it, but it works well enough. – Spidy Dec 21 '12 at 02:05

2 Answers2

3

Keeping a static list of instances is a fairly safe and normal thing to do. The main gotchas have to do with when you add items to the list.

For example, if Activity has a nontrivial constructor that calls addToComprehensiveList(this) when it starts, then there are times when not-fully-initialized objects are in a publicly accessible list. If your program is single-threaded, this isn't too dangerous - unless the constructor later throws an exception, in which case the object is left in the list in a not-fully-initialized state.

A safe way around this is to create your instances in a factory method that adds the object to the list after it is created. Of course, if there are no subclasses, just adding to the list as the last statement in the constructor works fine.

The other danger here is that getComprehensiveList() returns a reference to its instance list, which means that client code could be modifying that list without your class knowing. Even if the client just iterates through the list, you would get a commodification exception if you create a new Activity during their iteration. A safer approach is to return a copy of the list.

Russell Zahniser
  • 16,188
  • 39
  • 30
  • 1
    I realize this answer is somewhat long in the tooth, but, it really should be pointed out that this answer is only true in a single-threaded use of the static values and methods. In a multi-threaded use case (which is likely the case here - it *is* android), the use of this system is likely to cause numerous unexpected 'features'. – rolfl Jul 06 '14 at 01:05
-2

From my experience doing things like this, under heavy stress or memory use:

static ArrayList<Activity> allInstances; 

is not guaranteed to be available. The VM can null it out which is why Singleton might be a little safer.

Chuck D
  • 1,629
  • 2
  • 16
  • 32
  • If this was wikipedia I would insert a **citation neeeded** mark directly after `is not guaranteed to be available.` – Simon Forsberg Dec 21 '12 at 02:42
  • "From my experience", citation would be my SO handle – Chuck D Dec 21 '12 at 02:45
  • I just find it hard to believe that a static variable would not be available and that the VM can "null it out". – Simon Forsberg Dec 21 '12 at 02:53
  • Well, I used this concept to manage instances across activities in a libgdx game and after a while, the static was null. I never nulled it out in my code so why I suggested singleton. I don't know the dalvik internals but statics aren't safe/guaranteed. – Chuck D Dec 21 '12 at 02:56
  • A source I've found says that "(...) static variables, which are held per-classloader, not per-VM". http://tech.puredanger.com/2007/07/03/pattern-hate-singleton/ . Might that be the cause for your experience? – Simon Forsberg Jan 07 '13 at 21:23
  • @SimonAndréForsberg - Thanks for the article. There's another comment from one of the platform engineers referenced here (http://stackoverflow.com/a/9087658/838023) that suggests allocating memory in the native heap is managed by different rules than the VM. When I allocated significant space in the NDK via PixMaps in libgdx, I would see static lists get wiped out on older phones which could correlate to what's suggested in your article. – Chuck D Jan 08 '13 at 04:57
  • Good. Now just one more question: Singletons also use static variables, is there any guarantee that the singleton is always available, since the static variable above is not guaranteed? – Simon Forsberg Jan 08 '13 at 11:57
  • No same issue here but at least if it's null, you can new it in Singleton.Instance(); – Chuck D Jan 10 '13 at 04:55