android handler.java,Android Handler理解

Handler是什么

Handler是Android 线程间通信工具类。

一般用于子线程向主线程发送消息,将子线程中执行结果通知主线程,从而在主线程中执行UI更新操作。

源码角度理解

Handler负责发送(sendMessage)和处理消息(handleMessage)

1)Message:消息载体,包含消息id(what)、消息处理对象(obj)、Runnable接口等。Handler发送一条消息后,会将该消息加入到MessageQueue统一消息处理队列中。

2)MessageQueue:消息队列。用来存放Handler发送的消息的队列,单链表实现

3)Looper:消息泵,通过Looper.loop( )创建一个死循环,不断地从MessageQueue中抽取Message,Message通过绑定的内部target(handler类型),msg.target.dispatchMessage(msg)将该消息传给对应的Handler接收。在dispatchMessage方法内调用handleCallback或handleMessage方法

ThreadLocal理解

创建Handler对象时,需要先为这个Handler创建Looper.prepara( )新建一个looper对象。一个线程中只会有一个looper。因为looper使用ThreadLocal.set方法。在set方法中,会对应着当前Thread,将Looper存储在其成员变量ThreadLocalMap中。其中key是ThreadLocal,value是looper。因此looper-threadLocal-Thread是一一对应关系。

实际上ThreadLocal的值是放入了当前线程的一个ThreadLocalMap实例中,所以只能在本线程中访问,其他线程无法访问。

对象存放在哪里

在Java中,栈内存归属于单个线程,每个线程都会有一个栈内存,其存储的变量只能在其所属线程中可见,即栈内存可以理解成线程的私有内存。而堆内存中的对象对所有线程可见。堆内存中的对象可以被所有线程访问。

###Handler发送和处理消息过程分析

Handler发送消息:Handler.sendMessage(Message message)

Handler处理信息:

new Handler(){

// 通过复写handlerMessage()从而确定更新UI的操作

@Override

public void handleMessage(Message msg) {

...// 需执行的UI操作

}

};

sendMessage方法将message 入队messageQueue(单链表实现)在ActivityThread中会调用Looper.prepareMainLooper()生成looper,looper中会创建MessageQueue 。Looper.loop( )中有个死循环,不断从messageQueue中取message。

public static void main(String[] args) {

Looper.prepareMainLooper();

long startSeq = 0;

if (args != null) {

for (int i = args.length - 1; i >= 0; --i) {

if (args[i] != null && args[i].startsWith(PROC_START_SEQ_IDENT)) {

startSeq = Long.parseLong(

args[i].substring(PROC_START_SEQ_IDENT.length()));

}

}

}

ActivityThread thread = new ActivityThread();

thread.attach(false, startSeq);

if (sMainThreadHandler == null) {

sMainThreadHandler = thread.getHandler();

}

Looper.loop();

throw new RuntimeException("Main thread loop unexpectedly exited");

}

Looper类

private Looper(boolean quitAllowed) {

mQueue = new MessageQueue(quitAllowed);

mThread = Thread.currentThread();

}

public static void loop() {

...// 仅贴出关键代码

// 1. 获取当前Looper的消息队列

final Looper me = myLooper();

final MessageQueue queue = me.mQueue;

for (;;) {

Message msg = queue.next();

if (msg == null) {

return;

}

// next():取出消息队列里的消息

// 若取出的消息为空,则线程阻塞

// 2.2 派发消息到对应的Handler

msg.target.dispatchMessage(msg);

// 把消息Message派发给消息对象msg的target属性

// target属性实际是1个handler对象

// 3. 释放消息占据的资源

msg.recycle();

}

}

Handler中的dispatchMessage方法

public void dispatchMessage(Message msg) {

if (msg.callback != null) {

handleCallback(msg);

} else {

if (mCallback != null) {

if (mCallback.handleMessage(msg)) {

return;

}

}

handleMessage(msg);

}

}

今年金九银十我花一个月的时间收录整理了一套知识体系,如果有想法深入的系统化的去学习的,可以点击传送门,我会把我收录整理的资料都送给大家,帮助大家更快的进阶。

format,png

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值