Android的消息循环与Handler机制理解
一、概念
1、事件驱动型
什么是事件驱动?就是有事了才去处理,没事就躺着不动。假如把用户点击按钮,滑动页面等这些都看作事件,事件产生后程序就执行相应的处理方法,就是属于事件驱动型。
2、消息循环
把需要处理的事件表示成一个消息,并且把这个消息放入一个队列。消息循环就是一循环,for或者while都一样。从消息队列里面取出未处理的消息,然后调用该消息的处理方法。
3、Handler
最开始碰到handler是需要在子线程里面更新UI的时候。android的UI更新只能在主线程中进行,但是在子线程中执行的逻辑又需要更新UI,例如文件下载,在子线程中访问网络下载之后,就是更新下载进度。这个时候就需要使用Hanlder,准确的说是要发送一个进度更新的消息。什么是Handler?我的理解是消息的处理者。create消息对应一个create的Handler,destroy消息对应一个destroy的Handler。
二、实现
只是说说概念太假了,下面就来实现一个简单的消息处理机制。
1、Msg
把产生的事件用消息来表示,数据用各个参数传递。
public class Msg implements Serializable{
//序列化标识
private static final long serialVersionUID = -2414053244664115328L; //该消息的处理者。
private int handlerId; //参数。
public Object arg1;
public Object arg2; //大量参数
public Object array[]; public Msg(int handlerId) {
this.handlerId=handlerId;
} public void setHandlerId(int handlerId) {
this.handlerId=handlerId;
}
public int getHandleId() {
return handlerId;
}
}
2、Handler
事件的处理者
public abstract class Handler {
//唯一标识,由Looper分配
private int id; //使用该Handler的Looper
private Looper looper; public Handler(Looper looper) {
this.looper=looper;
id=looper.addMsgHandler(this);
} //消息处理函数
abstract public boolean handleMsg(Msg msg); //添加一个未处理消息。
public void sendMsg(Msg msg) {
looper.addMsg(msg);
} //返回该handler的信使。
public Msg obtainMsg() {
return new Msg(id);
}
}
3、Looper
消息循环
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.Queue; public class Looper {
private int handlerCount=0;
//消息队列。
private Queue<Msg> msgQueue=new LinkedList<Msg>();
//消息的处理。
private Map<Integer, Handler> msgHandler=new HashMap<>(); //loop
public void loop() {
for(;true;)
if(!msgQueue.isEmpty())
if(!distributeMsg(msgQueue.poll()))
//当消息处理返回false时。程序结束。
break;
} //添加处理消息的handler
public int addMsgHandler(Handler handler) {
handlerCount++;
msgHandler.put(handlerCount,handler);
return handlerCount;
} //添加待处理的消息
public void addMsg(Msg msg) {
msgQueue.add(msg);
} //消息分发
private boolean distributeMsg(Msg msg) {
Handler handler=msgHandler.get(msg.getHandleId());
if(handler!=null) {
handler.handleMsg(msg);
}else {
//出现未知消息,程序结束。
System.out.println("exit");
return false;
}
return true;
}
}
4、模拟生命周期
abstract class Basic{
private Looper mainLooper=new Looper();
private Handler sysHandler=new Handler(mainLooper) {
@Override
public boolean handleMsg(Msg msg) {
if(msg.arg1.equals("create")) {
onCreate();
}
if(msg.arg1.equals("destroy")) {
onDestroy();
}
return true;
}
}; public Basic() {
Msg m=sysHandler.obtainMsg();
m.arg1="create";
sysHandler.sendMsg(m);
//新获取一个Msg,不能沿用上一个。
m=sysHandler.obtainMsg();
m.arg1="destroy";
sysHandler.sendMsg(m);
} public Looper getMainLooper() {
return mainLooper;
} /**
* 生命周期
*/
abstract public void onCreate();
abstract public void onDestroy();
}
上面的代码创建了一个抽象类Basic,在里面注册了一个处理create和destroy两个消息的Handler。
5、子线程调用主线程的方法。
public class Main extends Basic{
private final Handler handler
=new Handler(getMainLooper()) {
@Override
public boolean handleMsg(Msg msg) {
// TODO Auto-generated method stub
System.out.println("msg.arg1="+msg.arg1+",Tid="+
Thread.currentThread().getId());
getMainLooper().addMsg(new Msg(-1));
return true;
}
};
public void onCreate() {
System.out.println("..............onCreate");
System.out.println("mainThread Tid="+Thread.currentThread().getId());
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("childThread Tid="+Thread.currentThread().getId());
Msg msg=handler.obtainMsg();
msg.arg1="childCall";
handler.sendMsg(msg);
}
}).start();
}
@Override
public void onDestroy() {
// TODO Auto-generated method stub
System.out.println(".............onDestroy");
//getMainLooper().addMsg(new Msg(-1));
}
public static void main(String[] args) {
new Main().getMainLooper().loop();
}
}
6、结果
结果分析,首先是两个生命周期的方法被调用,其次是实现了子线程调用主线程的方法。这里子线程转到主线程的原因是因为Looper运行在主线程,消息由Looper分发处理。
Android的消息循环与Handler机制理解的更多相关文章
- Android源码分析笔记--Handler机制
#Handler机制# Handler机制实际就是实现一个 异步消息循环处理器 Handler的真正意义: 异步处理 Handler机制的整体表述: 消息处理线程: 在Handler机制中,异步消息处 ...
- Android中的Handler机制
直接在UI线程中开启子线程来更新TextView显示的内容,运行程序我们会发现,如下错 误:android.view.ViewRoot$CalledFromWrongThreadException: ...
- Handler机制与生产者消费者模式
本文梳理了 Handler 的源码,并详细阐述了 Handler 与生产者消费者模式的关系,最后给出了多版自定义 Handler 实现.本文首发于简书,重新整理发布. 一.Handler Handle ...
- Android之消息机制Handler,Looper,Message解析
PS:由于感冒原因,本篇写的有点没有主干,大家凑合看吧.. 学习内容: 1.MessageQueue,Looper,MessageQueue的作用. 2.子线程向主线程中发送消息 3.主线程向子线程中 ...
- Android的消息循环机制 Looper Handler类分析
Android的消息循环机制 Looper Handler类分析 Looper类说明 Looper 类用来为一个线程跑一个消息循环. 线程在默认情况下是没有消息循环与之关联的,Thread类在ru ...
- android 进程间通信 messenger 是什么 binder 跟 aidl 区别 intent 进程间 通讯? android 消息机制 进程间 android 进程间 可以用 handler么 messenger 与 handler 机制 messenger 机制 是不是 就是 handler 机制 或 , 是不是就是 消息机制 android messenge
韩梦飞沙 韩亚飞 313134555@qq.com yue31313 han_meng_fei_sha messenger 是什么 binder 跟 aidl 区别 intent 进程间 通讯 ...
- Android Handler的使用示例:结合源码理解Android Handler机制(一)
什么是Handler? Android 的官方解释: 文档分节1:A Handler allows you to send and process Message and Runnable objec ...
- Android的消息机制: Message/MessageQueue/Handler/Looper
概览 * Message:消息.消息里面可包含简单数据.Object和Bundle,还可以包含一个Runnable(实际上可看做回调). * MessageQueue:消息队列,供Looper线程 ...
- 聊一聊Android的消息机制
聊一聊Android的消息机制 侯 亮 1概述 在Android平台上,主要用到两种通信机制,即Binder机制和消息机制,前者用于跨进程通信,后者用于进程内部通信. 从技术实现上来说,消息机制还是比 ...
随机推荐
- Java——检测其他线程的状态以及启动已死亡的线程
这次这个的思路是在主类中维护一个map,map的key是线程名,value是线程的状态,然后创建周期执行的线程通过检测这个map来判断进程的状态,如果有死亡的进程就把该进程启动. 首先是主类,这里的m ...
- 【0812 | Day 13】闭包函数/装饰器/迭代器
目录 闭包函数 无参装饰器 有参装饰器 迭代器 闭包函数 一.什么是闭包? 闭包指的是:函数内部函数对外部作用域而非全局作用域的引用. def outter(): x = 1 def inner(): ...
- C# 基于NPOI+Office COM组件 实现20行代码在线预览文档(word,excel,pdf,txt,png)
由于项目需要,需要一个在线预览office的功能,小编一开始使用的是微软提供的方法,简单快捷,但是不符合小编开发需求, 就另外用了:将文件转换成html文件然后预览html文件的方法.对微软提供的方法 ...
- (三)(1)线程间通信---wait和notify的使用
这篇博客记录线程间通信相关api使用以及理解. 首先第一点,我之前的博客里的线程之间也是通信的,但是他们的通信是建立在访问的是同一个变量上的,相当于是变量.数据层面上的通信,而下面要讲的是线程层面上的 ...
- ansible模块介绍之ios_command
一.模块简介 ios_command此模块将任意命令发送到ios节点并返回设备读取的结果 此模块不支持在配置模式下使用,即只支持在用户模式>和特权模式#下使用 官方文档地址:https://do ...
- IoT时代:Wi-Fi“配网”技术剖析总结
导读 近年来,物联网市场竞争激烈,从物联网平台厂商,设备生产商,到服务提供商,都在涌入这片红海.预计到2020年,全球联网设备数量将达到260亿个,年复合增长率达到20%:全球联网设备带来的数据将达到 ...
- Jetbrains好用的插件(经验总结)
# Jetbrain好用的插件(经验总结) 笔者使用过idea,phpstorm,webstorm,pycharm和goland开发过项目,不得不说,Jetbrains的编辑器每一款都挺好用的,而且快 ...
- RSA加密的java实现
首先科普一波: RSA的1024位是指公钥及私钥分别是1024bit,也就是1024/8=128 Bytes RSA算法密钥长度的选择是安全性和程序性能平衡的结果,密钥长度越长,安全性越好,加密解密所 ...
- Hadoop RPC机制详解
网络通信模块是分布式系统中最底层的模块,他直接支撑了上层分布式环境下复杂的进程间通信逻辑,是所有分布式系统的基础.远程过程调用(RPC)是一种常用的分布式网络通信协议,他允许运行于一台计算机的程序调用 ...
- 深刻剖析spring三种注入方式以及使用注解的原理
概述 注释配置相对于 XML 配置具有很多的优势: 它可以充分利用 Java 的反射机制获取类结构信息,这些信息可以有效减少配置的工作.如使用 JPA 注释配置 ORM 映射时,我们就不需要指定 PO ...