I am using a handler
object to continue UI work after finished a time consuming task in a seperate thread. Had a problem of the above Lint warning and following was my approach.
[ Sample Handler object type 1 ] ->
Handler responseHandler = new Handler()
{
@Override
public void handleMessage(Message msg)
{
super.handleMessage(msg);
Toast.makeText(MainActivity.this, "Finished the long running task in seperate thread...", Toast.LENGTH_LONG).show();
}
};
[ Sample Handler object type 2 ] ->
Handler responseHandler = new Handler(new Handler.Callback()
{
@Override
public boolean handleMessage(Message msg)
{
Toast.makeText(MainActivity.this, "Finished long running task in a seperate thread...", Toast.LENGTH_LONG).show();
return false; // RETURN VALUE ????
}
});
In the seperate thread(other than UI) when the time consuming task is done, it executes the following line to get the control back to UI thread(basically to the handler obj).
responseHandler.sendEmptyMessage(0);
The program works really fine with both types of handler objects, but with 1st type I am getting a Lint warning saying This Handler class should be static or leaks might occur.
Therefore I started using the 2nd type of handler object to avoid the Lint warning but the problem I've got is, I am not sure about the meaning of return value (true/false) in the 2nd way and also it works with either. I searched for this in google for so much but didn't get an exact answer explained this return value.
Yes, I saw this question had asked in many places in stackoverflow mainly reagrding the Lint warning, but my question is mainly about the return type in the 2nd way and to get it confirm if it's alright the way I solve the issue using the 2nd type of handler Obj.
Questions ->
1). Does anybody know what exacly this return value means(true/false) ?
2). Is it the correct thing I have done to get rid of the lint warning?
Thanks...
Each handler is bound to the Looper
of a thread, each Message
is placed on a data structure, a message queue.
Message
has a target
variable that points to a Handler
, a callback
variable that points to a Runnable
.
So, If you are using an anonymous class to create a Handler
object (like in the first example), then know that anonymous/non-static inner classes hold a reference to outer objects (Activity ?). So, the message posted on queue, might be holding references to the Handler
as target, and the Handler
in turn holding a reference to the outer class, like Activity
.
Now, a message can stay in the message queue for long intervals of time, as long as the thread is running. Meanwhile, the activity may have been dismissed. But it won't be garbage collected due to the obscure indirect reference of it, which the message has. Note that the Looper and Message Queue stay around as long as the thread is running.
In the second example, you are not creating an anonymous Handler
class. You are using the handler constructor and passing it an anonymous Callback
object. This might stop Lint from complaining, But I doubt this is a good approach. Just avoid inner classes, avoid passing Activity or context references to Handler.
Update:
The Handler's dispatchMessage()
gets messages due to be processed, where it checks if a callback has been provided, then if callback is provided, it doesn't calls handleMessage()
, if callback's handleMessage()
returns true:
public void dispatchMessage(Message msg) {
if (msg.callback != null) {
handleCallback(msg);
} else {
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
handleMessage(msg); //--won't be called if you return true.
}
}
I found some important info about memory leak by inner class like handler and want to share with you :
How to Leak a Context: Handlers & Inner Classes And I think the overridden method of Handler class will not return anything as you can check : handleMessage()
You have overridden Java Handler class not Android Handler, you can see handleMessage() of Java Handler class is having return statement and you can check reason also for return statement over here : boolean handleMessage(C context)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With