Android 为什么使用Handler

先解释下Java中的Handler和Android中Handler的区别。

java的Handler和android的handler其实一点关系都没有。

                   Java的Handler用于处理日志的,管理一下日志级别,是打印还是发到网络啊还是怎么滴

                   Android 的Handler 用于处理消息队列的


       然后说主题,Android中为什么使用handler呢?

        要理解这个问题要先弄清楚Andriod中的线程机制,涉及到以下几个类:

              Hander,Looper,MessageQueue

       在Android中,耗时操作不能放在主线程中,避免ANR,这是常识。在Android中,新启一个线程,然后用调用在线程中调用hander的sendMessage()发送一个通知,通知Handler去处理消息。

如果消息太多怎么存放呢,这要放到消息队列(MessageQueue)中,怎么管理呢?用Looper去循环。怎么在消息队列中插入新的消息呢?用Handler。


解释下:

Android 的looper和handler 其实是同事,做的都是Android中线程之间传递消息的。
看下ApI  默认情况下,新建一个线程是没有消息循环(Looper)的,Looper对象通过MessageQueue来存放消息和事件。一个线程只能有一个Looper,对应一个MessageQueue。

要想在线程中建立一个Looper,需要创建一个Looper对象。
注:Looper的构造器是私有的,在prepare()方法包含了创建一个新的Looper并放在线程中,如果已经有Looper则不能调用此方法。 然后调用Looper.loop()启动循环。   记得用Looper.quit()关闭循环。注:循环关闭了消息队列就不能用。

class LooperThread extends Thread {
	      public Handler mHandler;
	      public Looper mLooper;


	      public void run() {
	    	  Message msg = new Message();
	    	  msg.obj = "";
	    	  msg.what = 1;
	    	  mHandler.sendMessage(msg);
	    	  //创建一个Looper
	          Looper.prepare();
	          // 获取looper对象
	          mLooper = Looper.myLooper();
	          mHandler = new Handler() {
	              public void handleMessage(Message msg) {
	            	  switch (msg.what) {
					case 1:
						
						break;


					default:
						break;
					}
	            	  // 处理队列中的消息
	            	  //退出循环
	            	  mLooper.quit();
	              }
	          };


	          //开启循环
	          Looper.loop();
	      }
	  }
大多数的消息互动,是通过Handler进行的。


Android 中 新启动的线程是不带Looper的,需要自己启动和关闭,UI线程系统自己有一个Looper。'
新起一个带Looper的线程应该是这样的,new Thread(),new 一个Looper,放Thead 的本地数据中,
然后Looper 再new 一个消息队列(Message Queue)。

那Handler 的作用是什么呢?都说Handler和Looper进行通信,他们是怎么进行消息传递的呢?
其实Handler是对Looper的消息队列进行处理的,就是拿到Looper的消息队列,往里面插入消息。可以看下Handler的的构造器源码
mLooper = Looper.myLooper();
mQueue = mLooper.mQueue;
handler获取了当前线程的消息队列。
然后在用sendMessageAtTime()发送消息的时候(其实Handler发送消息最后都是用的这个方法)。
   MessageQueue queue = mQueue;
        if (queue != null) {
            //把msg.target 设置成自己(接收消息的Handler)
            msg.target = this;
            //  在消息队列中插入消息
            sent = queue.enqueueMessage(msg, uptimeMillis);
        }
看下消息队列在插入消息的时候执行了什么吧。
 final boolean enqueueMessage(Message msg, long when) {
        if (msg.isInUse()) {
            throw new AndroidRuntimeException(msg
                    + " This message is already in use.");
        }
        if (msg.target == null && !mQuitAllowed) {
            throw new RuntimeException("Main thread not allowed to quit");
        }
        final boolean needWake;
        synchronized (this) {
            if (mQuiting) {
                 //如果已经执行过Looper.quit()了就不要再加了
                RuntimeException e = new RuntimeException(
                    msg.target + " sending message to a Handler on a dead thread");
                Log.w("MessageQueue", e.getMessage(), e);
                return false;
            } else if (msg.target == null) {
                //消息没的处理,队列整个就没用了
                mQuiting = true;
            }


            msg.when = when;
            //Log.d("MessageQueue", "Enqueing: " + msg);
            Message p = mMessages;//当前消息
            //如果当前没有消息在处理或者执行时间比较优先
            if (p == null || when == 0 || when < p.when) {
                msg.next = p;//把当前消息放到下一个
                mMessages = msg;//插进来的消息放在当前
                //这个消息在最前面
                needWake = mBlocked; // new head, might need to wake up
            } else {
                Message prev = null;
                //如果当前有消息,并且优先级比插入进来的高
                while (p != null && p.when <= when) {
                    prev = p;  
                    p = p.next;
                }
                msg.next = prev.next;
                prev.next = msg;
                //等当前的消息处理完,不许呀唤醒
                needWake = false; // still waiting on head, no need to wake up
            }
        }
        if (needWake) {
            //JNI调用 唤醒方法
            nativeWake(mPtr);
        }
        return true;
    }

 回归到刚开始的问题,Android中为什么用Handler?其实这是一种设计模式,为了方便对消息队列进行消息处理。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值