Handler使用与源码分析

Handler主要用于异步消息处理:Handler发送消息到MessageQueue,Looper循环从MessageQueue中拿出消息Message,然后交给Handler处理。

一、Handler使用

1.1.创建handler的两种方式

方式一:

private Handler handler1 = new Handler(new Handler.Callback() {
        @Override
        public boolean handleMessage(@NonNull Message msg) {
            return false;
        }
    });

方式二:

private Handler handler2= new Handler(){
        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
        }
    };

1.2.发送消息

在子线程中发送消息到UI线程

new Thread(new Runnable() {
            @Override
            public void run() {
                Message message = new Message();
                message.what=3;
                message.obj="Hello";
                handler1.sendMessage(message);
                //延时发送消息
                //handler1.sendMessageDelayed(message,3000);
            }
        });

1.3.在UI线程处理消息

在handler中收到消息,做相应的处理,如更新UI

注意:消息以链表的结构存放在MessageQueue,时间优先队列

二、handler的内存泄漏问题

handler必须手动的去销毁,否则activity的销毁并不能讲handler销毁,这样会造成Looper.loop()的循环,从而内存泄漏。

2.1.解决内存泄漏的方法一

public void test(){
        new Thread(new Runnable() {
            @Override
            public void run() {
                Message message = new Message();
                message.what=3;
                //延时发送消息
                handler1.sendMessageDelayed(message,3000);
            }
        });
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        handler1.removeMessages(3);
    }

2.2.解决内存泄漏的方法二

public void test(){
        new Thread(new Runnable() {
            @Override
            public void run() {
                Message message = new Message();
                message.what=3;
                SystemClock.sleep(3000);
                if (handler1!=null) handler1.sendMessage(message);
            }
        });
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        handler1.removeMessages(3);
        handler1=null;
    }

三、为什么不能在子线程创建handler

应用在启动的时候,会启动ActivityThread,ActivityThread中有一个main方法,会调用Looper.prepareMainLooper();获取一个Looper对象,而我们在子线程获取的Looper是在应用启动时主线程创建的,所以在子线程创建的Handler是拿不到Looper的,这个时候就回抛出异常。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值