Android Threading: this handler class must be static or a leak may occur

I use the handler object to continue working with the user interface after completing the multitask task in a separate thread. Had the problem of Lint's aforementioned warning and the next been my approach.

[Handler object type of example 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(); } }; 

[Type of sample handler object 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 a separate thread (except for the user interface), when a laborious task is performed, it executes the following line to return control to the user interface thread (mainly for the obj handler).

 responseHandler.sendEmptyMessage(0); 

The program works fine with both types of handler objects, but with the 1st type I get a Lint warning saying . This handler class must be static or a leak may occur .

Therefore, I started using a type 2 handler object to avoid the Lint warning, but the problem I received is not sure about the value of the return value (true / false) in the 2nd way, and it also works with them. I searched this on google so much, but did not get an exact answer, explained this return value.

Yes, I saw that in many places this question was asked on stackoverflow, mainly overflowing the Lint warning, but my question mainly concerns the type of return in the second method and for confirming whether this is good, how I solve the problem using the 2nd handler type Obj.

Questions →

1). Does anyone know what this means that the return value means (true / false)?

2). Did I do it right to get rid of the pile warning?

Thanks...

+6
source share
2 answers

Each handler is attached to a Looper stream, each Message is placed in a data structure, a message queue.

Message has a target variable that points to a Handler variable, a callback that points to Runnable .

So, if you use an anonymous class to create a Handler object (as in the first example), then you know that anonymous / non-static inner classes contain a reference to external objects (Activity?). Thus, a message placed in a queue may contain references to Handler as target, and Handler , in turn, contains a reference to an external class, for example, Activity .

Now the message can remain in the message queue for long intervals while the thread is running. Meanwhile, the activity may have been fired. But it will not be garbage collection due to an unclear indirect reference to it that has a message. Note that Looper and Message Queue are kept as long as the stream is running.

In the second example, you are not creating an anonymous Handler class. You use the handler constructor and pass it an anonymous callback object. This may prevent Lint from complaining, but I doubt this is a good approach. Just avoid inner classes, avoid passing actions or contextual references to a handler.

Update:

The dispatchMessage() handler receives messages that need to be processed, where it checks whether a callback has been provided, then if a callback is provided, it does not call handleMessage() if callback 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. } } 
+5
source

I found important information about a memory leak with an inner class, such as a handler, and I want to share with you:

Like a context leak: handlers and inner classes And I think that the redefined Handler class method will not return anything that you can check: handleMessage ()

You redefined the Java handler class, not the Android handler, you can see that the handleMessage () of the Java Handler class has a return statement, and you can also check the reason also for the return statement: boolean handleMessage (C context)

+1
source

Source: https://habr.com/ru/post/951618/


All Articles