我正在开发带有服务的Android 2.3.3应用程序。我在服务内部拥有此功能,可以与Main Activity 进行通信:

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());
    [ ... ]
}

在这里final Messenger mMessenger = new Messenger(new IncomingHandler());,我得到以下Lint警告:
This Handler class should be static or leaks might occur: IncomingHandler
这是什么意思?

最佳答案

如果IncomingHandler类不是静态的,它将具有对Service对象的引用。

同一线程的Handler对象都共享一个公共(public)的Looper对象,它们将消息发布到其中并从中读取。

由于消息包含目标Handler,因此只要消息队列中存在带有目标处理程序的消息,就无法对处理程序进行垃圾回收。如果处理程序不是静态的,则即使您的ServiceActivity被销毁,也无法对其进行垃圾回收。

只要消息保留在队列中,这至少可能会导致内存泄漏至少一段时间。除非您发布长时间延迟的邮件,否则这并不是什么大问题。

您可以将IncomingHandler设为静态,并为您的服务添加一个WeakReference:

static class IncomingHandler extends Handler {
    private final WeakReference<UDPListenerService> mService;

    IncomingHandler(UDPListenerService service) {
        mService = new WeakReference<UDPListenerService>(service);
    }
    @Override
    public void handleMessage(Message msg)
    {
         UDPListenerService service = mService.get();
         if (service != null) {
              service.handleMessage(msg);
         }
    }
}

请参阅Romain Guy的post 以获取更多引用

关于android - 此类Handler类应该是静态的,否则可能会发生泄漏: IncomingHandler,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/11407943/

10-10 10:21