Henry
Henry

Reputation: 951

should my Handler object be static?

I know if I am sub-classing a Handler class in Android, it better be static, or memory leak might happen. like this:

static class MyHandler extends Handler {...}

But what if I am simply constructing an object of class Handler? like this:

Handler mHandler = new Handler();

Should it be static? like this:

static Handler mHandler = new Handler();

Since a default Handler will use the default (main) thread and there will be only one main thread in a process. Does it means mHandler should not be a non-static field in my component class (ie. Activity, Receiver, ...)? Thanks.

------------------update more info--------------------- thanks for your quick response. but all following answers are not what I am asking.

the problem is, the Handler object "attaches" itself to a process by default. (technically, it attaches to the main thread)

which means its life cycle is not attached to an activity or a receiver.

so, if I make it an activity's non-static field, isn't it not that right?

(my question is more "theoretical/logical", not "practical")

Upvotes: 1

Views: 1195

Answers (2)

Nir Alfasi
Nir Alfasi

Reputation: 53535

pskink pointed to the following (excellent) article in his comment above: http://www.androiddesignpatterns.com/2013/01/inner-class-handler-memory-leak.html

This is valuable information for an Android developer (and actually to any Java developer as well!): an inner-class which is not static holds (an implicit) reference to the outer-class (the Activity). So in situations where the inner-class lives longer than the outer-class, the outer-class won't be eligible to garbage collection until the inner-class is. Or in other words - this can lead to memory leaks!

In Android, configuration changes, for example, could cause an Activity-object to get destroyed and a new one to be created. In such a scenario, if the handler (which was defined as an inner non-static class) is still running - the GC won't be able to clean the Activity-object.

All the above has nothing to do with how you declare the variable that holds the handler. That variable can be static or non-static: the keyword static has different meanings in different context - so when we refer to a class variable, setting it as static means that it is shared by all the objects of this class (unlike non-static variable - which is created and accessed: one per object).

Back to our previous example: setting the variable that holds the Handler as static means that only one such object will be created for the Activity class, so even if configuration changes take effect and the Activity object gets destroyed and a new one is created - the new one will keep using the same (static) Handler.

Upvotes: 1

jollarvia
jollarvia

Reputation: 379

a static class wouldn't be able to invoke instances of itself anyway so no. That's actually the definition of static. What you really want to know is how to clean up non-static objects and that is pretty easy.

The Java Virtual Machine has a garbage disposal phase that periodically checks for references to living objects. If a living object has no reference, JVM sweeps it in the trash.

for instance, if your handler is in a code block, like in a while loop or in a function or whatever,

{
   Handler testHandler = new Handler();
}

when that block ends, testHandler can no longer be reached. It has no reference to it and garbage disposal will handle it. So I wouldn't worry too much about it except in like an infinite loop where each loop itteration is capable of making a new Handler() in a arrayList outside the loop because then the Handlers never die and eventually you use all your memory and you crash.

But those are neccessarily contrived test cases. They don't really happen often but I assume you are probably making a game if you are asking about memory and Android at all and games have infinite loops so that's what you need to be careful of.

You can delete objects by just setting them to null. null is a special object and there is no actual reference made at all so it is low memory to set a variable to null. Unfortunately unless it goes out of scope at some point there is a little bit of memory used to house the name of the variable. But in java there is no other (good) way of getting rid of it.

Upvotes: 1

Related Questions