Memory leaks caused by handler in Android

Source: Internet
Author: User

In Android common programming, handler is often used when asynchronous operations are performed and the returned results are processed. Usually our code will do that.

123456789 public class sampleactivity extends Activity { Private final Handler Mleakyhandler = new Handler () {@Overridepublic void Handlemessage (Message msg) {//... }}}

However, the above code can lead to memory leaks, and when you use the Android Lint tool, you get this warning

In Android, Handler classes should is static or leaks might occur, Messages enqueued on the application thread ' s messagequ Eue also retain their target Handler. If The Handler is a inner class, its outer class would be retained as well. To avoid leaking the outer class, declare the Handler as a static nested class with a weakreference to its outer class

See here, there may be some confusing, where in the code can lead to memory leaks, and how to cause memory leaks? Let's analyze it slowly.

1) When an Android app starts, it automatically creates a Looper instance that is used by the main thread. The main job of Looper is to handle a message object in a message queue. In Android, all Android frame events (such as activity lifecycle method calls and button clicks) are put into the message and then added to the message queue that looper to process, and the looper is responsible for processing one line at a time. The Looper life cycle in the main thread is as long as the current application.

2) When a handler is initialized on the main thread, we send a target for this handler message to the Looper processing message queue, and the message that has actually been sent already contains a reference to the handler instance. Only then Looper can call Handler#handlemessage (message) to complete the correct handling of the message when it is processed to this message.

3) in Java, non-static inner classes and anonymous inner classes implicitly hold references to their external classes. Static inner classes do not hold references to external classes. For this content you can view the words Java: "Invalid" private modifier

It is true that the above code example is a bit difficult to detect a memory leak, so the following example is very obvious

1234567891011121314151617181920212223 public class sampleactivity extends Activity { Private final Handler Mleakyhandler = new Handler () { @Override public void handlemessage (Message msg) { // ...} }@Override protected void onCreate (Bundle savedinstancestate) { super.oncreate (savedinstancestate);//Post a message and delay its execution for ten minutes.Mleakyhandler.postdelayed (New Runnable () { @Override public void Run () {/ * ... */} },+ * ); //Go to the previous Activity.Finish (); }}

After analyzing the code above, when we perform the activity's finish method, the deferred message will be present in the main thread message queue for 10 minutes before it is processed, and the message contains the handler reference, and handler is an instance of an anonymous inner class. It holds a reference to the outside of the sampleactivity, so this causes the sampleactivity not to be recycled, which leads to sampleactivity holding a lot of resources that cannot be recycled, which is what we often call a memory leak.

Note that the above new runnable is also implemented in the anonymous inner class, which also holds the sampleactivity reference and prevents Sampleactivity from being recycled.

To solve this problem, the idea is not applicable to non-static inner classes, when inheriting handler, either in a separate class file, or using static internal classes. Because static inner classes do not hold references to external classes, they do not cause memory leaks for external class instances. When you need to invoke external activity in a static inner class, we can use a weak reference to handle it. Also on the same need to set runnable to static member properties. Note: A static anonymous inner class instance does not hold a reference to an external class. The code that will not cause a memory leak after modification is as follows

1234567891011121314151617181920212223242526272829303132333435363738394041424344 public class sampleactivity extends Activity { /*** Instances of static inner classes does not hold a implicit * reference to their outer class. */private static class MyHandler extends Handler { Private final weakreference<sampleactivity> mactivity; public MyHandler (sampleactivity activity) { Mactivity =new weakreference<sampleactivity> (activity);}@Override public void handlemessage (Message msg) { Sampleactivity activity = Mactivity.get ();if (activity! = null) { // ...} } }Private final MyHandler Mhandler = new MyHandler (this); /*** Instances of anonymous classes does not hold a implicit * reference to their outer class when they is "static". */private static final Runnable srunnable = new Runnable () { @Override public void Run () {/ * ... */} };@Override protected void onCreate (Bundle savedinstancestate) { super.oncreate (savedinstancestate);//Post a message and delay its execution for ten minutes.Mhandler.postdelayed (Srunnable,+ * ); //Go to the previous Activity.Finish (); }}

In fact, many of the memory leaks in Android are caused by the use of non-static internal classes in the activity, as mentioned in this article, so when we use a non-static inner class, we should pay special attention to if its instance holds the object life cycle is greater than its outer class object, Then it is possible to cause a memory leak. Individuals tend to use static classes of articles and weak references to solve this problem.

Original: How to Leak a Context:handlers & Inner Classes

Memory leaks caused by handler in Android

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.