处理程序内存泄漏?

Handler Memory Leak?

我有一个在主线程上声明的处理程序:

  mainHandler = new Handler() {

            @Override
            public void handleMessage(Message msg) {

                switch (msg.what) {

                    case 1:

                        Bundle bundle = msg.getData();
                        mTextView.setText(bundle.getString("message"));
                        break;

                    . . .

                    default:
                        super.handleMessage(msg);
                        break;
                }
            }
        };

其中 mTextView 是在 Create() 上定义的 TextView。

我有一个任务在单独的线程中使用。 runnable 从主线程存储 mainHandler 并告诉它发送消息:

public class SomeRunnable implements Runnable {

    private Handler mHandler;

    public SomeRunnable(Handler handler) throws IOException {
        . . .    
        mHandler = handler;
    }

    @Override
    public void run() {

        while (!Thread.currentThread().isInterrupted()) {
            try {
                    . . .

                    Message msg = mHandler.obtainMessage();
                    . . .
                    mHandler.sendMessage(msg);
                }

            } catch (IOException e) {
                Log.e("Error", e.hashCode() + ": " + e.getLocalizedMessage());
            }
        }
    }

我发现如果 Handler class 不是静态的,则使用 Handler#postDelayed() 等方法可能会造成内存泄漏。但是,我正在使用 Handler#sendMessage() 立即将消息放入消息队列。

我还有内存泄漏的危险吗?即使有:

  @Override
    protected void onDestroy() {
        super.onDestroy();

        mThread.interrupt();
        mainHandler.removeCallbacksAndMessages(null);
    }

谢谢!

为了解决所有可能的问题,您可以将 mHandler 设为 WeakReference,如下所示:

public class SomeRunnable implements Runnable {

    private WeakReference<Handler> mHandlerRef;

    public SomeRunnable(Handler handler) throws IOException {
        . . .    
        mHandlerRef = new WeakReference<Handler>( handler );
    }

    @Override
    public void run() {

        while (!Thread.currentThread().isInterrupted()) {
            try {
                    . . .
                    Handler mHandler = mHandlerRef.get();
                    if( mHandler != null ) {
                        Message msg = mHandler.obtainMessage();
                        . . .
                        mHandler.sendMessage(msg);
                    }
                }

            } catch (IOException e) {
                Log.e("Error", e.hashCode() + ": " + e.getLocalizedMessage());
            }
        }
    }
}