Android基础——多线程之Handler

一、概述

Handler是Android系统一个重要的框架,主要用于异步更新UI,首先看下Handler的流程图

文字解读一下流程图:

1、Looper中存放着MessageQueen,MessageQueen存放着很多Message,Handler发送messages前会获取Looper;

2、Handler通过post(Runnable r)或者sendMessage(Message msg)将封装的message发送到对应Looper的MessageQueen中;

3、在Looper.loop的带动下,MessageQueen不断的获取Message并通过dispatchMessage发送给Handler;

4、Handler通过HandlerMessage来处理接受到的messages

 

涉及到的文件类知识点

  • Handler(处理者) 
    1. 定义:Message的主要处理者
    2. 作用:负责发送Message到消息队列&处理Looper分派过来的Message
  • Looper(循环器) 
    1. 定义:扮演Message Queue和Handler之间桥梁的角色
    2. 作用: 
      消息循环:循环取出Message Queue的Message 
      消息派发:将取出的Message交付给相应的Handler
  • Message Queue(消息队列) 
    1. 定义:采用单链表的数据结构来存储消息列表
    2. 作用:用来存放通过Handler发过来的Message,按照先进先出执行
  • Message(消息) 
    1. 定义:Handler接收和处理的消息对象(Bean对象)
    2. 作用:通信时相关信息的存放和传递
  • ThreadLocal 
    1. 定义:线程内部的数据存储类
    2. 作用:负责存储和获取本线程的Looper

二、通信流程及问题解析

源码解析不做介绍了,搜索一大堆,从几个问题介绍一下流程

1、post(Runnable r)和sendMessage(Message msg)的区别?

2、一个Activity有多个handler怎么接受messages,就是怎样知道handler1发送的消息不会被handler2接收,同理handler2发送的消息不会被handler1接收

3、Android中为什么主线程不会因为Looper.loop()里的死循环卡死?https://www.zhihu.com/question/34652589

 

解答学习的过程:

1、post(Runnable r)和sendMessage(Message msg)的区别?

sendMessage方法,

/**
 * Pushes a message onto the end of the message queue after all pending messages
 * before the current time. It will be received in {@link #handleMessage},
 * in the thread attached to this handler.
 *  
 * @return Returns true if the message was successfully placed in to the 
 *         message queue.  Returns false on failure, usually because the
 *         looper processing the message queue is exiting.
 */
public final boolean sendMessage(Message msg)
{
	return sendMessageDelayed(msg, 0);
}

然后封装成一个Message,发送到MessageQueen中,获得msg.target = this;

private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
	msg.target = this;
	if (mAsynchronous) {
		msg.setAsynchronous(true);
	}
	return queue.enqueueMessage(msg, uptimeMillis);
}

post方法传入的是Runnable,做的也是封装Message,

/**
 * Causes the Runnable r to be added to the message queue.
 * The runnable will be run on the thread to which this handler is 
 * attached. 
 *  
 * @param r The Runnable that will be executed.
 * 
 * @return Returns true if the Runnable was successfully placed in to the 
 *         message queue.  Returns false on failure, usually because the
 *         looper processing the message queue is exiting.
 */
public final boolean post(Runnable r)
{
   return  sendMessageDelayed(getPostMessage(r), 0);
}

 区别在于getPostMessage(r)方法,m.callback = r;区别于sendMessage的msg.target = this;

private static Message getPostMessage(Runnable r) {
	Message m = Message.obtain();
	m.callback = r;
	return m;
}

接下来就看看dispatchMessage方法,

/**
 * Handle system messages here.
 */
public void dispatchMessage(Message msg) {
	if (msg.callback != null) {
		handleCallback(msg);
	} else {
		if (mCallback != null) {
			if (mCallback.handleMessage(msg)) {
				return;
			}
		}
		handleMessage(msg);
	}
}
  1. msg的callback不为空,调用handleCallback方法(message.callback.run()
  2. mCallback不为空,调用mCallback.handleMessage(msg)
  3. 最后如果其他都为空,执行Handler自身的 handleMessage(msg) 方法

 这样就解释了为啥post传入一个Runnable还可以在主线程中更新UI

2、一个Activity有多个handler怎么接受messages,就是怎样知道handler1发送的消息不会被handler2接收,同理handler2发送的消息不会被handler1接收

在上一题可以看到handler在enqueueMessage方法中,发送到MessageQueen中的messages有打上一个标记msg.target = this;

在分发messages时,Looper.loop中,有这样一行代码msg.target.dispatchMessage(msg);这样就拿到了对应标记的message分发给handler处理

3、Android中为什么主线程不会因为Looper.loop()里的死循环卡死?

这个参照一下Gityuan大神的解答,Android中为什么主线程不会因为Looper.loop()里的死循环卡死?

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值