Handler causes memory leak analysis
For memory leaks, poke a memory leak
new Handler() { @Override publicvoidhandleMessage(Message msg) { // do something. }}
When we create this Handler
, we Android Lint
will be prompted with such a warning: In Android, Handler classes should be static or leaks might occur.
.
There has been no careful analysis of the cause of the leak, the main reasons are listed first:
- Android
The first time the program is created, the default is Looper
to create an object that Looper
handles each of the Message Queue
Message
main threads that Looper
exist throughout the application's life cycle.
-When the main thread is Hanlder
created, it is associated with Looper
the Message Queue
Message
Message(排队的Message)
Current Reference when it is added to the message queue. Handler
Looper
called when processing to the current message Handler#handleMessage(Message)
. That means Looper
that before we deal with this Message
,
There will be a chain MessageQueue -> Message -> Handler -> Activity
that cannot be recycled because its references cause you to be held in a Activity
reference
- in Java, No-static's inner class implicitly holds a reference to the current class. The inner class of static is not.
Specific analysis
Public class sampleactivity extends Activity { Private FinalHandler Mhandler =NewHandler () {@Override Public void Handlemessage(Message msg) {//Do something} }@Override protected void onCreate(Bundle savedinstancestate) {Super. OnCreate (Savedinstancestate);//Send a message after 10 minutes of executionMhandler.postdelayed (NewRunnable () {@Override Public void Run() { } },600000);//End the current activityFinish ();}
At finish()
the time, it has Message
not been processed, Message
held Handler
, Handler
held Activity
, and this will cause the Activity
memory leak to occur without being recycled.
Workaround
- Protection through program logic.
- If
Handler
you're doing a time-consuming operation, Activity
stop your background thread when it's closed. The thread is stopped, which is equivalent to cutting off the Handler
line that is connected to the outside,
Activity
Nature will be recycled at the right time.
- if
Handler
is a Message with delay
, then on
Activity OnDestroy ()
method to call Handler
's remove*
method to remove the message object from the message queue.
- about
handler.remove*
methods
-
removecallbacks (Runnable R)
--clear m on R match Essage.
-
removec4allbacks (Runnable R, Object token)
-- When the R match is cleared and the Message,token matching token (message.obj) is empty, only R is matched.
-
removecallbacksandmessages (Object token)
-clears the message on the token match.
-
removemessages (int what)
--Match what you want
-
removemessages (int what, Object object)
--Match by what
we need to clear all Message (Callback)
with the Handler
as target
You can handler.removecallbacksandmessages (null)
by calling the following method:
- will be
Handler
declared as a static class.
Static classes do not hold objects of external classes, so you Activity
can be recycled at will. But not holding Activity
references, how do I go about manipulating Activity
some of the objects? We're going to use a weak reference here.
Public class myactivity extends Activity { PrivateMyHandler Mhandler;@Override protected void onCreate(Bundle savedinstancestate) {Super. OnCreate (Savedinstancestate); Mhandler =NewMyHandler ( This); }@Override protected void OnDestroy() {//Remove all Runnable and Message.Mhandler.removecallbacksandmessages (NULL);Super. OnDestroy (); }StaticClass MyHandler extends Handler {//WeakReference to the outer class ' s instance. PrivateWeakreference<myactivity> Mouter; Public MyHandler(myactivity activity) {Mouter =NewWeakreference<myactivity> (activity); }@Override Public void Handlemessage(Message msg) {myactivity outer = mouter.get ();if(Outer! =NULL) {//Do something with outer as your wish.} } }}
- Email: [Email protected]
- Good luck!
Handler causes memory leak analysis