A non-static internal class that holds references to an external Activity causes a memory leak.

private Handler handler = new Handler() { public void handleMessage(android.os.Message msg) { doSomeWork(); }};Copy the code

1) When using internal classes (including anonymous classes) to create a Handler, the Handler object implicitly holds a reference to an external class object (usually an Activity). . The Handler is usually accompanied by a time-consuming background thread (such as pulling an image from the network) that notifies the Handler via a message mechanism when the task is complete (such as downloading an image) and the Handler updates the image to the interface. However, if the user closes the Activity during a network request, the Activity is normally no longer in use, and it might be reclaimed during a GC check, but since the thread has not yet finished executing and holds a reference to Handler (how else would it send a message to Handler?). This Handler in turn holds a reference to the Activity, preventing the Activity from being recycled (i.e., a memory leak) until the network request ends (e.g., an image is downloaded).

2) Additionally, if you execute Handler’s postDelayed() method, which loads your Handler into a Message and pushes the Message to the MessageQueue, then until the delay you set arrives, There will be a chain of MessageQueue -> Message -> Handler -> Activity, causing your Activity to hold a reference and not be recycled.

How to solve ###? #####1. This Handler class should be static or leaks might occur (anonymous Android.os.handler) less… (Ctrl+F1) Since this Handler is declared as an inner class, it may prevent the outer class from being garbage collected. If the Handler is using a Looper or MessageQueue for a thread 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 follows: 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 instantiate the Handler; Make all references to members of the outer class using the WeakReference object.

Instead, static internal class defines Handler, and uses WeakReference to hold external Activity and interact with the Activity

private static class MyHandler extends Handler{ private WeakReference<MainActivity> mMyActivity; public MyHandler(MainActivity activity) { mMyActivity = new WeakReference<>(activity); } @Override public void handleMessage(Message msg) { final MainActivity activity = mMyActivity.get(); if (activity ! = null) { activity.doSomeWork(); }}}; public void doSomeWork() { // do }Copy the code

#####2. Clear the Message in time to solve the root cause of the MessageQueue -> Message -> Handler -> Activity reference chain

mHandler.removeCallbacksAndMessages(null);
Copy the code