我正在开发一个带有服务的Android 2.3.3应用程序。我在这个服务中有这个来与Main活动通信:

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警告:

这个Handler类应该是静态的,否则可能会发生泄漏

这是什么意思?


当前回答

我困惑。 我找到的例子完全避免了static属性,并使用UI线程:

    public class example extends Activity {
        final int HANDLE_FIX_SCREEN = 1000;
        public Handler DBthreadHandler = new Handler(Looper.getMainLooper()){
            @Override
            public void handleMessage(Message msg) {
                int imsg;
                imsg = msg.what;
                if (imsg == HANDLE_FIX_SCREEN) {
                    doSomething();
                }
            }
        };
    }

我喜欢这个解决方案的一点是,混合使用类变量和方法变量是没有问题的。

其他回答

正如其他人所提到的,Lint警告是因为潜在的内存泄漏。你可以通过传递一个处理程序来避免Lint警告。回调时构造Handler(即你不子类化Handler,没有Handler非静态内部类):

Handler mIncomingHandler = new Handler(new Handler.Callback() {
    @Override
    public boolean handleMessage(Message msg) {
        // todo
        return true;
    }
});

据我所知,这并不能避免潜在的内存泄漏。消息对象持有对mIncomingHandler对象的引用,该对象持有对Handler的引用。回调对象,该对象持有对Service对象的引用。只要Looper消息队列中有消息,服务就不会被GC。但是,除非消息队列中有长时间延迟的消息,否则这不会是一个严重的问题。

这种方法对我来说很有效,通过将处理消息的位置保留在它自己的内部类中,从而保持代码干净。

您希望使用的处理程序

Handler mIncomingHandler = new Handler(new IncomingHandlerCallback());

内部类

class IncomingHandlerCallback implements Handler.Callback{

        @Override
        public boolean handleMessage(Message message) {

            // Handle message code

            return true;
        }
}

我困惑。 我找到的例子完全避免了static属性,并使用UI线程:

    public class example extends Activity {
        final int HANDLE_FIX_SCREEN = 1000;
        public Handler DBthreadHandler = new Handler(Looper.getMainLooper()){
            @Override
            public void handleMessage(Message msg) {
                int imsg;
                imsg = msg.what;
                if (imsg == HANDLE_FIX_SCREEN) {
                    doSomething();
                }
            }
        };
    }

我喜欢这个解决方案的一点是,混合使用类变量和方法变量是没有问题的。

我不确定,但你可以尝试初始化处理程序为空在onDestroy()

如果您正在使用Kotlin,只需在声明嵌套类时删除inner关键字即可。

Kotlin中的嵌套类默认情况下是静态的,使用inner声明它们使它们成为非静态的。

将嵌套的Handler子类声明更改为

class myService : Service() {

inner class IncomingHandler : Handler(Looper.getMainLooper()) {
/////
}

}

to

class myService : Service() {

class IncomingHandler : Handler(Looper.getMainLooper()) {
/////
}

}