整理自:
问题:
下面的代码会有这样的告警:
代码如下:
This Handler class should be static or leaks might occur
: IncomingHandler
public class UDPListenerService extends Service{ private static final String TAG = "UDPListenerService"; //private ThreadGroup myThreads = new ThreadGroup("UDPListenerServiceWorker"); private UDPListenerThread myThread; /** * Handler to communicate from WorkerThread to service. */ private Handler mServiceHandler; // Used to receive messages from the Activity final Messenger inMessenger = new Messenger(new IncomingHandler()); // Use to send message to the Activity private Messenger outMessenger; class IncomingHandler extends Handler { @Override public void handleMessage(Message msg) { } } /** * Target we publish for clients to send messages to Incoming Handler. */ final Messenger mMessenger = new Messenger(new IncomingHandler()); [ ... ]}
原因分析:
If
IncomingHandler
class is not static, it will have a reference to yourService
object.(因为非静态内部类的实例会拥有生成它的父类实例的引用)。
Handler
objects for the same thread all share a common Looper object, which they post messages to and read from.As messages contain target
Handler
, as long as there are messages with target handler in the message queue, the handler cannot be garbage collected. If handler is not static, yourService
orActivity
cannot be garbage collected, even after being destroyed.This may lead to memory leaks, for some time at least - as long as the messages stay in the queue. This is not much of an issue unless you post long delayed messages.
You can make
IncomingHandler
static and have aWeakReference
to your service:
static class IncomingHandler extends Handler { private final WeakReferencemService; IncomingHandler(UDPListenerService service) { mService = new WeakReference (service); } @Override public void handleMessage(Message msg) { UDPListenerService service = mService.get(); if (service != null) { service.handleMessage(msg); } }}