Android 38: Memory leaks that may be caused by handler in use

Source: Internet
Author: User

Descriptive narrative of the problem

Once upon a time, we used the original method to use handler will have the following a warm hint:

classstaticor leaks might occur

Here's a more specific description (warning on Android Studio, not knowing if Eclipse is the same)

Since This Handler is declared as a inner class, it may prevent the outer class from being garbage collected. If the Handler is using a Looper or MessageQueue for a thread and other than the main thread, then there is no issue. If the Handler is using the Looper or MessageQueue of the main thread, you need to fix your Handler declaration, as follow S:declare the Handler as a static class; In the outer class, instantiate a weakreference to the outer class and pass this object to your Handler when you Instantia Te the Handler; Make all references to the outer class using the WeakReference object.

It probably means:

Once handler is declared as an inner class, it may cause its external classes not to be garbage collected. Assume that handler is using Looper or MessageQueue (Message Queuing) on other threads (which we typically become worker thread). Instead of the main thread (the UI thread), then there is no problem.

Assuming handler uses Looper or MessageQueue on the main thread, you need to make a declaration of handler such as the following changes:
Declares handler as a static class. Instantiate an external class's WeakReference (weak reference) in an external class and pass in the object to your handler when handler is initialized; Use the WeakReference object for all referenced external class members.

Solution One

The above descriptive narrative basically put the recommended change method clearly expressed. The following code is an implementation of my own use, please refer to:

PrivateCopyfilehandler Mhandler;@Overrideprotected void onCreate(Bundle savedinstancestate) {Super. OnCreate (Savedinstancestate);    Setcontentview (R.layout.activity_appstart); Mhandler =NewCopyfilehandler ( This); Startcopydbthread ();}Private void Startcopyfilethread() {LOG.D (TAG,"Startcopydbthread");NewThread (NewRunnable () {@Override         Public void Run() {//do SOMETHING like:copydbfile ();Message Msg=mhandler.obtainmessage ();        Mhandler.sendmessage (msg); }}). Start ();}Private Static  class copyfilehandler extends Handler {Weakreference<appstartactivity> mactivity; Public Copyfilehandler(appstartactivity activity) {mactivity =NewWeakreference<> (activity); } Public void Handlemessage(Message msg) {FinalAppstartactivity activity = Mactivity.get ();//handle you message here!}}
Why are memory leaks

So why not do this will cause a memory leak?
This is related to several keywords: inner class, Handler message loop (Looper), Java garbage collection mechanism.
It should be emphasized that not every use of handler causes a memory leak. There is a certain probability that a specific condition will be required to cause a leak.


the inner class will have a reference to the outer class.
convention in the garbage collection mechanism. When an object in memory has a reference count of 0 o'clock. will be recycled.
Handler as an asynchronous message processing mechanism on Android (well, I mostly use the worker thread to synchronize with the UI thread), and it needs to work with Looper and MessageQueue. Simply put, a loop body (Looper) is maintained to handle Message Queuing (MessageQueue).

A message is removed from the MessageQueue once per loop. The corresponding message handler function is then recalled.

Suppose, I mean, if there's a message in the loop body that's not processed (in the message queue), then handler will always be there. The reference count of the handler external class (typically activity) is not 0, so the external class cannot be garbage collected.

This is why very many people encounter activity OnDestroy methods that have not been running.

There's another way to try it out.

The warning description mentions that handler used Looper or MessageQueue in the worker thread, and I tried it a bit. Please taste them.

    PrivateHandler Testhandler;Private ThreadMthread= New Thread() { Public voidRun () {Log.DTAG,"Mthread Run"); Looper.Prepare (); Testhandler= NewHandler () { Public voidHandlemessage (Message msg) {Log.D"TAG","worker thread:"+Thread.CurrentThread ().GetName ()); Switch (msg.What) {//handle message here}                }            }; Looper.Loop(); }    };//start thread here    if(Thread.State.NEW ==Mthread.GetState ()) {Log.DTAG,"Mthread Name:" +Mthread.GetName ()); Mthread.Start (); }//send message hereTesthandler.Sendemptymessage (1);

References:
Http://stackoverflow.com/questions/11407943/this-handler-class-should-be-static-or-leaks-might-occur-incominghandler
http://m.blog.csdn.net/blog/wurensen/41907663
http://blog.csdn.net/lmj623565791/article/details/38377229

Android 38: Memory leaks that may be caused by handler in use

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.