Android基础-Handler

简述

Handler解决多线程问题(主线程才能修改UI界面),子线程可以通过Handler与主线程通信来更改UI界面。

作用

  • 子线程发送消息
  • 主线程中获取、处理消息

方法及作用

方法作用
handleMessage处理消息,重写该方法实现对消息的处理工作
hasMessage检查消息队列中是否有指定消息
sendEmptyMessage发送空消息
sendMessage发送消息
sendEmptyMessageDelayed延迟(毫秒)发送空消息
sendMessageDelayed延迟(毫秒)发送消息
removeMessages删除消息队列存在的指定消息(全部)

Hanlder、Loop、MessageQueue

  • Hanlder发送和处理消息
  • MessageQueue保存消息,并且以先进先出的方式管理消息(线程必须要有MessageQueue才可以正常使用Hanlder)
  • Looper:循环读取MessageQueue中的消息,并且交给对应的Handler处理(每一个线程只能拥有一个Looper)

在主线程中,系统以及初始化了Looper对象,因此主线程中可以直接创建使用Handler。而在子线程中,我们需要自行创建Looper对象。

private Looper()   
{  
    mQueue  =  new MessageQueue();  
    mRun  =  true;  
    mThread  = Thread.currentThread();  
}  

在Looper的构造方法中会创建MessageQueue,然而该构造函数是私有的,无法调用。想要创建Looper对象,需要调用它的prepare方法,prepare方法中会进行判断,保证当前线程中只有一个Looper对象。


public static void prepare() {
    prepare(true);
 }

private static void prepare(boolean quitAllowed) {
      if (sThreadLocal.get() != null) {
         throw new RuntimeException("Only one Looper may be created per thread");
      }
      sThreadLocal.set(new Looper(quitAllowed));
}

private Looper(boolean quitAllowed) {
     mQueue = new MessageQueue(quitAllowed);
     mThread = Thread.currentThread();
}

在创建Looper对象之后,需要调用它的loop方法开启循环提取消息。loop方法为一个死循环,会不断的获取MessageQueue中的消息,并且指派给相应的Handler。

for (;;) {
	  Message msg = queue.next(); // might block
	  if (msg == null) {
		// No message indicates that the message queue is quitting.
		  return;
	  }

	  // This must be in a local variable, in case a UI event sets the logger
	  Printer logging = me.mLogging;
	 if (logging != null) {
		 logging.println(">>>>> Dispatching to " + msg.target + " " +
				 msg.callback + ": " + msg.what);
	}

	msg.target.dispatchMessage(msg);

	 if (logging != null) {
		 logging.println("<<<<< Finished to " + msg.target + " " + msg.callback);
	}

	 // Make sure that during the course of dispatching the
	 // identity of the thread wasn't corrupted.
	 final long newIdent = Binder.clearCallingIdentity();
	 if (ident != newIdent) {
		 Log.wtf(TAG, "Thread identity changed from 0x"
				 + Long.toHexString(ident) + " to 0x"
				 + Long.toHexString(newIdent) + " while dispatching to "
				 + msg.target.getClass().getName() + " "
				+ msg.callback + " what=" + msg.what);
	 }

	 msg.recycleUnchecked();
}

线程中Looper使用步骤

  1. 调用 Looper的prepare()方法为当前线程创建Looper对象,创建Looper对象时,它的构造器会创建与之配套的MessageQueue。
  2. 有了Looper之后,创建Handler子类的实例,重写HandlerMessage()方法,该方法负责处理来自其它线程的消息。
  3. 调用Looper的loop()方法启动Looper。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值