Android Handler 机制原理

来源:互联网 发布:淘宝哪家的玉是真的 编辑:程序博客网 时间:2024/05/23 02:07

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

全文完!





原创粉丝点击