现在的位置: 首页 > 综合 > 正文

对于Handler的一点理解。

2014年02月03日 ⁄ 综合 ⁄ 共 2334字 ⁄ 字号 评论关闭

Handler:

A Handler allows you to send and process Message and Runnable objects associated with a thread'sMessageQueue.
Each Handler instance is associated with a single thread and that thread's message queue. When you create a new Handler, it is bound to the thread / message queue of the thread that is creating it -- from that point on, it will deliver messages and runnables
to that message queue and execute them as they come out of the message queue.

以上是Handler的官方概述。

以前只是半知半解的用着Handler。知道在Activity里面创建一个Handler,然后再实现一个Runnable。在Runnable中向Handler发送一个Message即可实现多线程操作。

看文档中的 Each Handler instance is associated with a single thread and that thread's message queue. 这句话我一直以为我们创建的Handler是和我们new的那个Thread关联着呢。后来我直接new了多个Thread都向这个Handler发送Message。我发现也不报错啊,当时没在意。直到后来用到Handler.postDelayed(Runnable,long)这个函数的时候。我发现也没有new Thread()怎么可以直接用Runnable呢。那么这个Handler是和哪个Thread关联着得呢?

发现这些问题后然后又去看文档,发现文档中还有这句: When you create a new Handler, it is bound to the thread / message queue of the thread that is creating it。

看懂了这一句这些问题就都明白了。这个Handler是和创建它的那个Thread的关联。我们创建Handler是在主线程中。所以我们平时直接创建的Handler是和主线程关联的。

那么Handler.postDelayed(Runnable,long)这个方法就可以解释了。

是在主线程中等待long毫秒后执行Runnable这个动作。

我不知道是不是只有我自己有这个误解。以为Handler是和new出来的Thread一对一关联呢。所以写出来提个醒。

另外。还有Looper这个对象,虽然我们平时用的不多但他确实是存在的。在主线程中是默认有个Looper的对象的。所以我们平时不用管,尽管使用Handler就行了。当你在其他线程中(自己new一个Thread的情况)创建一个Handler的时候你会发现按平时的用法是执行不了的。

另外,Handler的Messagequene中,如果不去调用Handler.sendMessage()这个方法去发送消息的话。消息队列中是没有消息的。Handler的 sendMessage()和handleMessage()两个方法是对立的。sendMessage()是向消息队列里(MessageQuene)发送消息。handleMessage()是从消息队列里取出消息来执行。就是执行handleMessage里面的方法。

然后关于Handler的使用,并不是只有启动一个新线程的时候才可以用,主线程中同样可以向消息队列发送消息,然后执行。例如可以达到延时操作的效果。

例如

	class RefreshHandler extends Handler {
		@Override
		public void handleMessage(Message msg) {
			System.out.println("here");
		}

		private void sleep(long delayMillis) {

			this.removeMessages(0);
			sendMessageDelayed(obtainMessage(0), delayMillis);
		}
	}

	private RefreshHandler refreshHandler = new RefreshHandler();

	public void test1() {
		refreshHandler.sleep(300);
	}

当调用sleep()这个函数的时候就会300毫秒后向MessageQuene发送消息。然后执行handleMessage().方法里的内容。

Handler会向message queue通过两种方法发送消息:sendMessage或post。这两种消息都会插在message queue队尾并按先进先出执行。但通过这两种方法发送的消息执行的方式略有不同:通过sendMessage发送的是一个message对象,会被Handler的handleMessage()函数处理;而通过post方法发送的是一个runnable对象,则会自己执行。 

  Handler中分发消息的一些方法
        post(Runnable)
        postAtTime(Runnable,long)
        postDelayed(Runnable long)
        sendEmptyMessage(int)
        sendMessage(Message)
        sendMessageAtTime(Message,long)
        sendMessageDelayed(Message,long)

抱歉!评论已关闭.