在使用Handler时如何避免出现内存泄露

在Android开发中使用Handler出现了内存泄漏问题或者HandlerLeak警告

public class MainActivity extends Activity {
    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
         //...
        }
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        go();
    }
    private void go(){
        Message message = Message.obtain();
        mHandler.sendMessage(message);
    }
}
@SuppressLint("HandlerLeak")
private Handler mHandler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);
        //...
    }
};

这种创建Handler的方式会造成内存泄漏,由于mHandler是Handler的非静态匿名内部类的实例,所以它持有外部类Activity的引用,我们知道消息队列是在一个Looper线程中不断轮询处理消息,那么当这个Activity退出时消息队列中还有未处理的消息或者正在处理消息,而消息队列中的Message持有mHandler实例的引用,mHandler又持有Activity的引用,所以导致该Activity的内存资源无法及时回收,引发内存泄漏
避免出现内存泄露的方法:

public class MainActivity extends Activity {
    private final Myhandler mHandler = new Myhandler(this);
    private static class Myhandler extends Handler{
        private WeakReference<MainActivity > mActivity;

        public Myhandler(MainActivity activity) {
            mActivity = new WeakReference<MainActivity >(activity);
        }

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            MainActivity activity = mActivity.get();

            /*
             * if (mActivity.get() == null) { 
             *      return; 
             * } 
             *     //...
             */
            if (activity != null) {
                //...
            }
        }
}

创建一个静态Handler内部类,然后对Handler持有的对象使用弱引用,这样在回收时也可以回收Handler持有的对象,这样虽然避免了Activity泄漏,不过Looper线程的消息队列中还是可能会有待处理的消息,所以我们在Activity的Destroy时或者Stop时应该移除消息队列中的消息

@Override
protected void onDestroy() {
    super.onDestroy();
    mHandler.removeCallbacksAndMessages(null);
}

使用mHandler.removeCallbacksAndMessages(null),是移除消息队列中所有消息和所有的Runnable;当然也可以使用mHandler.removeCallbacks()或mHandler.removeMessages(),来移除指定的Runnable和Message

@Override
protected void onDestroy() {
    super.onDestroy();
    mHandler.removeMessages(int what); 

    mHandler.removeCallbacks(Runnable mRunnable);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值