Solution to memory leak caused by handler in Android

In common Android programming, handler is often used when performing asynchronous operations and processing the returned results. Usually our code will do this.

However, in fact, the above code may lead to memory leakage. You will get such a warning when you use the Android lint tool

See here, there may still be some unclear, where in the code may lead to memory leakage, and how does it lead to memory leakage? Let's analyze it slowly.

1. When an Android application starts, it will automatically create a looper instance for the main thread. The main work of looper is to process the message objects in the message queue one by one. In Android, all Android framework events (such as activity life cycle method calls and button clicks) are put into messages, and then added to the message queue to be processed by looper, which is responsible for processing one by one. The looper life cycle in the main thread is as long as the current application.

2. After a handler is initialized in the main thread, when we send a message with the target of this handler to the message queue processed by looper, the message already sent actually contains a reference to the handler instance. Only in this way can looper call handler #handlemessage (message) to complete the correct processing of the message when processing this message.

3. In Java, both non static inner classes and anonymous inner classes implicitly hold references to their outer classes. Static inner classes do not hold references to outer classes. For this content, you can see the private modifier of "invalidation" in Java

Indeed, the above code example is a little difficult to detect memory leakage, so the following example is very obvious

Analyze the above code. When we execute the finish method of the activity, the delayed message will exist in the message queue of the main thread for 10 minutes before being processed, and the message contains the reference of the handler. The handler is an anonymous internal class instance that holds the reference of the external sampleactivity, so the sampleactivity cannot be recycled, Many of the resources held by sampleactivity cannot be recycled because of this. This is what we often call memory leakage.

Note that the above new runnable is also implemented by anonymous inner classes. It will also hold the reference of sampleactivity and prevent sampleactivity from being recycled.

To solve this problem, the idea is not applicable to non static internal classes. When inheriting handler, it is either put in a separate class file or use static internal classes. Because the static inner class will not hold the reference of the outer class, it will not lead to memory leakage of the outer class instance. When you need to call external Activity in a static internal class, we can use weak references to handle it. In addition, you also need to set runnable as a static member property. Note: a static anonymous inner class instance does not hold a reference to an outer class. The modified code that will not cause memory leakage is as follows:

In fact, many memory leaks in Android are caused by the use of non static internal classes in activity, as mentioned in this article. Therefore, when we use non static internal classes, we should pay special attention. If the life cycle of the holding object of its instance is greater than that of its external class object, it may lead to memory leaks. Individuals tend to use static classes and weak references in articles to solve this problem.

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>