欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Android Handler 机制原理

程序员文章站 2022-07-14 19:50:19
...

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也就运行在同一个线程里

关系图

Android 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);
        }

    }


}

全文完!