Handler使用套路

上周做一个流量传感器的项目,基本功能是通过BLE实现主界面实时读取设备的数据,其他界面也有读写命令的操作,由于传感器不支持异步的读写操作,所以不同界面的切换需要确保先停止其他界面的读写操作。这部分功能我是用Handler异步更新机制来实现。
用到的功能点:
1、使用Handler延迟发送消息功能,实现一段时间后执行一个操作。
2、使用Handler移除消息发送功能,实现移除一个或多个操作。

套路1:如何正确的使用Handler,不容易发生内存泄露。

小白使用Handler:

public class MainActivity extends Activity{

    //...todo....

    public Handler mHandler=new Hander{
        @override
        public void handlerMessage(Message msg){
            switch(msg.what){
                case XXX:
                    //访问外部类的成员和方法,做一些操作
                    break;      
            }           
        }
    }

    //....todo...

但是呢,小白发现Lint检测时会提示这么一句话 : This Handler class should be static or leaks might occur。意为handler应用static修饰否则容易发生内存泄漏。
于是乎,小白就把Handler修改为static,但是发现Handler里面用到的外部类的成员和方法都要声明为static才能被使用。这个时候,小白就直接忽略这个Lint,无奈的等待随时可能发生的内存泄露。
(同一个线程下的handler共享一个looper对象,消息中保留了对handler的引用,只要有消息在队列中,那么handler便无法被回收,如果handler不是static,那么使用Handler的Service和Activity就也无法被回收,即便它们的ondestroy方法被调用。这就可能导致内存泄露。当然这通常不会发生,除非你发送了一个延时很长的消息。)
小强使用Handler:
机智的小强,首先自定义一个继承Handler的静态内部类,然后对Handler依赖的外部Activity使用了弱引用,不仅能够不影响Activity的正常回收而且能够方便地使用该activity实例获取其字段和方法,无需修改为static。代码如下:

public class MainActivity extends Activity{

    //....todo...

    static class MyHandler extends Handler {
            WeakReference<MainActivity> mActivity;

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

            @Override
            public void handleMessage(Message msg) {
                    MainActivity activity = mActivity.get();
                    switch (msg.what) {
                    case 0:
                            activity.doSomethings();
                            break;
                    }
            }
    };

    MyHandler mHandler = new MyHandler(MainActivity.this);

    //....todo...

}
套路2:如何有效的移除延迟发送的消息

参考:http://www.jianshu.com/p/e8f3c9e0b873

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值