你真的了解Handler嘛?

一.Handler是什么

Handler允许发送、处理消息和Runnuable。一个Handler只能绑定一个线程、一个线程只能绑定一个Looper

简言之,Handler就做了两件事:发送消息(或Runnuable)、处理消

息(或Runnable)。

第一件事:很好理解,体现在方法上就是:post,postDelayed,sendMessage,sendMessageDelay。

第二件事:第一件事发生后,Message入消息队列,按照时间先后进行排序。注意:消息队列,是优先级队列,排序方式是插入排序。这里,想一个问题,消息入队的时候,是如何保证线程安全的?既然队列中存在数据,Looper也开启了循环,那么每次循环,取出队列中的消息(第一个),进行回调处理。显而易见,这就是一个典型的“消费者-生产者”思想。

二.了解Handler的使用

1.Handler可以直接“new”吗?

主线程里是可以的,因为主线程里,已经创建了Looper。子线程,必须手动创建Looper,或者使用HandlerThread(内置Looper的线程),HandlerThread就不做解释了,主要核心就是如何创建Looper,并保证线程安全。

2.具体使用

这里的Handler,和主线程的Looper绑定,消息是从主线程发出的,回调也是主线程处理的。

public class MainActivity extends AppCompatActivity {

    private Handler handler = new Handler(new Handler.Callback() {
        @Override
        public boolean handleMessage(@NonNull Message msg) {
            switch (msg.what) {
                case 1:
                    Log.e("Tomato--->", "处理消息1");
                    break;
                case 2:
                    Log.e("Tomato--->", "处理消息2");
                    break;
            }
            return false;
        }
    });

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Message message = Message.obtain();
        message.what = 1;
        handler.sendMessage(message);
        Message message2 = Message.obtain();
        message2.what = 2;
        handler.sendMessage(message2);
    }

}

这里的Handler,和子线程的Looper绑定,消息是从主线程发出的,回调是在子线程处理的。

public class MainActivity extends AppCompatActivity {

    private Handler handler;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        HandlerThread handlerThread = new HandlerThread("thread-1");
        handlerThread.start();
        handler = new Handler(handlerThread.getLooper()) {
            @Override
            public void handleMessage(@NonNull Message msg) {
                super.handleMessage(msg);
                switch (msg.what) {
                    case 1:
                        Log.e("Tomato--->", "thread-1处理消息1");
                        break;
                    case 2:
                        Log.e("Tomato--->", "thread-1处理消息2");
                        break;
                }
            }
        };
        Message message = Message.obtain();
        message.what = 1;
        handler.sendMessage(message);
        Message message2 = Message.obtain();
        message2.what = 2;
        handler.sendMessage(message2);
    }

}

3.主要看一下sendMessage做了些什么

senMessage之后,一步步调用,最终追到这个方法,如下:

private boolean enqueueMessage(@NonNull MessageQueue queue, @NonNull Message msg,
        long uptimeMillis) {
    //一方面,Message绑定了Handler;另一方面,target==null说明是一个异步消息,需要优先处理
    //有关异步的消息发送,就不做解释,对于普通处理,没有帮助,而且,这个发送异步消息的方法,不对外暴露,就此作罢,有兴趣的,可以自行关注,尝试使用。
    msg.target = this;
    msg.workSourceUid = ThreadLocalWorkSource.getUid();

    if (mAsynchronous) {
        //设置为异步消息
        msg.setAsynchronous(true);
    }
    return queue.enqueueMessage(msg, uptimeMillis);
}

3-1.target绑定之后做了什么

target是Message中的属性,其实就是Handler,那么消息入队之后,Message自然就和Handler进行了绑定。

创建Handler之后,发送消息,然后处理回调,来跟进一下回调的时机,进入Handler,找到方法,如下:

public void dispatchMessage(@NonNull M
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值