一、概念

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机制理解的更多相关文章

  1. Android源码分析笔记--Handler机制

    #Handler机制# Handler机制实际就是实现一个 异步消息循环处理器 Handler的真正意义: 异步处理 Handler机制的整体表述: 消息处理线程: 在Handler机制中,异步消息处 ...

  2. Android中的Handler机制

    直接在UI线程中开启子线程来更新TextView显示的内容,运行程序我们会发现,如下错 误:android.view.ViewRoot$CalledFromWrongThreadException: ...

  3. Handler机制与生产者消费者模式

    本文梳理了 Handler 的源码,并详细阐述了 Handler 与生产者消费者模式的关系,最后给出了多版自定义 Handler 实现.本文首发于简书,重新整理发布. 一.Handler Handle ...

  4. Android之消息机制Handler,Looper,Message解析

    PS:由于感冒原因,本篇写的有点没有主干,大家凑合看吧.. 学习内容: 1.MessageQueue,Looper,MessageQueue的作用. 2.子线程向主线程中发送消息 3.主线程向子线程中 ...

  5. Android的消息循环机制 Looper Handler类分析

    Android的消息循环机制 Looper Handler类分析 Looper类说明   Looper 类用来为一个线程跑一个消息循环. 线程在默认情况下是没有消息循环与之关联的,Thread类在ru ...

  6. 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 进程间 通讯 ...

  7. Android Handler的使用示例:结合源码理解Android Handler机制(一)

    什么是Handler? Android 的官方解释: 文档分节1:A Handler allows you to send and process Message and Runnable objec ...

  8. Android的消息机制: Message/MessageQueue/Handler/Looper

    概览   * Message:消息.消息里面可包含简单数据.Object和Bundle,还可以包含一个Runnable(实际上可看做回调). * MessageQueue:消息队列,供Looper线程 ...

  9. 聊一聊Android的消息机制

    聊一聊Android的消息机制 侯 亮 1概述 在Android平台上,主要用到两种通信机制,即Binder机制和消息机制,前者用于跨进程通信,后者用于进程内部通信. 从技术实现上来说,消息机制还是比 ...

随机推荐

  1. dart的基本语法(一)

    Hello world ​ 安装dart的环境就不赘述了,无脑安装就可以了,安装过程中好像需要梯子(vpn),我装的时候失败好多次,我的梯子不能用了,准备不装了的时候,莫名其妙的装好了.迷の操作.惯例 ...

  2. 洛谷 P3413 SAC#1 - 萌数

    题意简述 求l~r之间存在长度至少为2的回文子串的正整数的个数 题解思路 数位DP 注意到有偶数长度的回文串必有长度为2的回文串,有奇数长度的回文串必有长度为3的回文串 所以只需判断与前一位,前两位是 ...

  3. 读取某个目录下的所有图片并显示到pictureBox

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  4. 使用 Docker 部署 Spring Boot

    Docker 技术发展为微服务落地提供了更加便利的环境,使用 Docker 部署 Spring Boot 其实非常简单,这篇文章我们就来简单学习下. 首先构建一个简单的 Spring Boot 项目, ...

  5. 重读《学习JavaScript数据结构与算法-第三版》- 第5章 队列

    定场诗 马瘦毛长蹄子肥,儿子偷爹不算贼,瞎大爷娶个瞎大奶奶,老两口过了多半辈,谁也没看见谁! 前言 本章为重读<学习JavaScript数据结构与算法-第三版>的系列文章,主要讲述队列数据 ...

  6. JMM内存模型详解(一)

    本文开始死磕JMM(Java内存模型)由于知识点较多,分来写 该文为JMM第一篇 技术往往是枯燥的,本文文字较多 1. JMM是什么? 其实JMM很好理解,我简单的解释一下,在Java多线程中我们经常 ...

  7. docker方式部署elk日志搜索平台

    Docker部署ELKF操作文档 前提介绍 1.之前搭建elk+f+k使用原生系统软件安装方式,由于docker镜像日趋成熟,docker官网和elastic官网都有相关镜像和各自安装文档可供参考,各 ...

  8. 如何使用python records 库优雅的操作数据库

    今天要介绍的这个python第三方库非常厉害,完美操作各种数据库.名字叫 records, 在网上很少有这个库的相关资料,但是在开源社区可是很火热的哦.如果这还不能打消你的顾虑,再告诉你一件事:如果你 ...

  9. Java中不得不谈的值传递和地址传递

    个人的一些认识,希望能对初学Java的你,或者困惑于方法参数传递的你祈祷一丝帮助! 下面是一些作者的个人观点,如果有错,欢迎各位大牛指出错误,灰常感谢您的观看与支持... -------------- ...

  10. Python之高阶函数如何理解?

    我们先要了解一下什么是所谓的高阶函数: 看定义:什么是高阶函数? 高阶函数:我们知道一个函数可以作为参数传给另外一个函数,或者一个函数的返回值为另外一个函数(若返回值为该函数本身,则为递归),如果满足 ...