Android Handler 机制原理

Handler 概述

在Android系统中实现了一套类似的消息处理机制。在下面介绍handler机制前,首先得了解以下几个概念:
1. Message
消息,理解为线程间通讯的数据单元。例如后台线程在处理数据完毕后需要更新UI,则可发送一条包含更新信息的Message给UI线程。
2. Message Queue
消息队列,用来存放通过Handler发布的消息,按照先进先出执行。
3. Handler
Handler是Message的主要处理者,负责将Message添加到消息队列以及对消息队列中的Message进行处理。
4. Looper
循环器,扮演Message Queue和Handler之间桥梁的角色,循环取出Message Queue里面的Message,并交付给相应的Handler进行处理。
5. 线程
UI thread 通常就是main thread,而Android启动程序时会替它建立一个Message Queue。

Handler的定义

handler是Android给我们提供来更新UI的一套机制,也是一套消息处理机制
android在设计的时候封装了一套消息创建、传递、处理机制

Handler使用方法

1,传递Message,用于接收子线程发送的数据,并用此数据配合主线程更新UI

1.void handleMessage( Message msg):处理消息的方法,该方法通常被重写。
2.final boolean hasMessage(int what):检查消息队列中是否包含有what属性为指定值的消息
3.final boolean hasMessage(int what ,Object object) :检查消息队列中是否包含有what好object属性指定值的消息
4.sendEmptyMessage(int what):发送空消息
5.final Boolean send EmptyMessageDelayed(int what ,long delayMillis):指定时间(毫秒)发送空消息
6.final boolean sendMessage(Message msg):允许安排一个带数据的Message对象到队列中,等待更新
一,使用Handler在子线程中向UI线程发送一个消息进行UI更新
二,创建一个Message,Message msg=new Message();msg.arg1=12;msg.obj=***;可以传递对象
7.final boolean sendMessageDelayed(Message msg,long delayMillis):指定多少时间(毫秒)之后发送消息

2.传递Runnable对象。用于通过Handler绑定的消息队列,

post(Runnable)
post(Runnable,long)
postDelaved(Runnable long)
post类允许你排列一个Runnable对象到主线程中,比如 使用PostDelayed方法,两秒后调用此Runnable对象 ,handler.postDelayed(runnable, 2000); ,实际上也就实现了一个2s的一个定时器

3.传递Callback对象,CallBack用于截获handler发送的消息,返回true就截获成功

public Handler tHandler=new Handler(new Handler.Callback() {
    @Override
    public boolean handleMessage(Message message) {
        return false;
    }


});

Handler 原理

Handler封装了消息发送
Looper:内部包含一个消息队列也就是MessageQueue ,所以的Handler此队列发送的消息都走向这个队列
Looper.loop(),该方法是个for死循环,不断的从MessageQueue取消息,有消息就处理消息,没有就阻塞
MessageQueue,消息队列,可以添加消息,处理消息
Handler
在构造Handler的时候内部会跟Looper进行关联,通过Looper.myLooper()获取到Looper,找到Looper,也就找到了MessageQueue。在Handler中发送消息,其实是向MessageQueue中发送消息.

Handler,Looper和MessageQueue的关系

Looper和MessageQueue一一对应,创建一个Looper的同时,会创建一个MessageQueue。而Handler与它们的关系,只是简单的聚集关系,即Handler里会引用当前线程里的特定Looper和MessageQueue。这样说来,多个Handler都可以共享同一Looper和MessageQueue了。当然,这些Handler也就运行在同一个线程里

关系图


Handler与子线程

Handler不仅可以更新UI,你完全可以在一个子线程中去创建一个Handler,然后使用这个handler实例在任何其他线程中发送消息,最终处理消息的代码都会在你创建Handler实例的线程中运行

class  TestThread extends Thread{
        public Handler handler;
        @Override
        public void run() {
            super.run();
            Looper.prepare();
            handler=new Handler(){
                @Override
                public void handleMessage(Message msg) {
                    super.handleMessage(msg);
                    Log.i("tttt",Thread.currentThread().getName());
                }
            };
            Looper.loop();
        }
    }

一般UI主线程不做耗时操作,我们通过子线程消息来处理耗时操作

来看下HandlerThread

HandlerThread本质上就是一个普通Thread,只不过内部建立了Looper.其实使用HandlerThread的效果和使用Thread+Handler差不多

   private HandlerThread mHandlerThread;
    //子线程中的handler
    private Handler mThreadHandler;
 private void initThread()
    {
        mHandlerThread = new HandlerThread("check-message-coming");
        mHandlerThread.start();

        mThreadHandler = new Handler(mHandlerThread.getLooper())
        {
            @Override
            public void handleMessage(Message msg)
            {
                update();//模拟数据更新

                if (isUpdateInfo)
                    mThreadHandler.sendEmptyMessage(MSG_UPDATE_INFO);
            }
        };

    }
      private void update()
    {
        try
        {
            //模拟耗时
            Thread.sleep(2000);
            mMainHandler.post(new Runnable()
            {
                @Override
                public void run()
                {
                    String result = "每隔2秒更新一下数据:";
                    result += Math.random();
                    tvMain.setText(result);
                }
            });

        } catch (InterruptedException e)
        {
            e.printStackTrace();
        }

    }

主线程和子线之间的信息交互

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ThreadTest threadTest=new ThreadTest();
        new Thread(threadTest).start();//开启子线程
    }


    private Handler handler=new Handler(){
        // 接收消息
        public void handleMessage(Message msg){
            switch (msg.arg1) {
                case 1:
                  Log.i("tttt","");
                    break;
                default:
                    break;
            }
        }
    };

    // 创建子线程,在子线程中处理耗时工作
    private class ThreadTest implements Runnable{
        public void run() {
            // TODO Auto-generated method stub
            try{
                Thread.sleep(1000);
            }
            catch (Exception e) {
                e.printStackTrace();
            }
            Message msgMessage=new Message();
            msgMessage.arg1=1;
            handler.sendMessage(msgMessage);
        }

    }


}

全文完!





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

揽m月

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值