Handler使用

一、相关概念

Handler是一套消息传递机制,通常的作用是在多线程的应用场景中,将子线程(工作线程)中需要更新UI的相关信息传递到主线程,从而实现工作线程对UI的更新。

概念 定义 作用 备注
主线程
(UI线程、MainThread)
应用程序首次开启时会自动开启一条线程,其实就是主线程 处理和UI相关操作 不可进行耗时操作
子线程
(工作线程)
手动开启的线程 主要进行耗时操作 子线程通过Handler与主线程通信
消息
(Message)
线程间通信的数据单元 存储通信信息
消息队列
(Message Queue)
一种先进先出的数据结构
(底层是单向链表实现)
存储和管理Handler发送来的消息 创建Looper时同时创建Message Queue
处理者
(Handler)
子线程和主线程通信的媒介
线程信息的主要处理者
添加消息队列
处理Looper分发过来的消息
创建Handler时,Looper必须存在
循环器
(Looper)
消息队列与Handler的通信媒介 无限循环
获取消息:从消息队列取出消息
分发消息:将取出消息分发给对应Handler
每个线程最多只能对应一个Looper(只能创建一次)
一个Looper可以被多个Handler绑定
一个Handler只能绑定一个Looper

二、使用方式

Handler的使用方式可以根据发送消息的方式不同而分为两种:

Handler.sendMessage和Handler.post()

三、使用步骤

方式一:使用Handler.sendMessage()

根据创建Handler的方式不同,又可分两种:创建Handler子类、使用匿名类,但本质都是相同的,都是继承Handler类创建子类

  • 创建Handler子类:

1.自定义Handler子类,并重写handleMessage()方法

static class MyHandler extends Handler {

        WeakReference<Activity> weakReference;

        public MyHandler(Activity activity){
            weakReference = new WeakReference<>(activity);
        }

        //重写handleMessage()方法
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (weakReference.get() == null) {
                //activity被回收
                return;
            }
            //执行的UI操作
        }
    }

2.主线程创建Handler实例

private MyHandler myHandler = new MyHandler(this);

3.在子线程中创建需要发送的消息对象

Message msg = Message.obtain();
msg.what = 1;

4.在子线程中通过Hander发送消息到消息队列

myHandler.sendMessage(message);

5.启动子线程

  • 使用匿名类:

1.在主线程中通过匿名内部类创建Handler类对象

Handler mhandler =  new Handler(){
    //重写handleMessage()方法
    @Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);
        //执行的UI操作 
    }
};

2.在子线程中创建需要发送的消息对象

Message msg = Message.obtain();
msg.what = 1;

3.在子线程中通过Hander发送消息到消息队列

mhandler .sendMessage(msg);

4.启动子线程

方式二:使用Handler.post()方法

1.在主线程中创建Handler实例

private Handler mhandler = new Handler();

2.在子线程中使用Handler.post()发送消息

 mhandler.post(new Runnable() {
            @Override
            public void run() {
                //执行的UI操作
            }
        });

3.启动子线程

posted on 2024-05-29 22:33  广坤山货  阅读(21)  评论(0编辑  收藏  举报