Android Threading: This Handler class should be static or leaks might occur
android, android-handler, java
Solution
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.
}
}
Problem
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...