目录

1,handler消息循环机制

2,post和sendMessage区别

1,handler消息循环机制

Android中的线程之前要通讯,通常使用的是Handler机制进行通讯,我们开启一个线程通常是不具备线程之间的通讯能力的,想让它具备通讯能力需要在线程中启动Looper,如下

class LooperThread extends Thread {

public Handler mHandler;

public void run() {

Looper.prepare();

mHandler = new Handler() {

public void handleMessage(Message msg) {

// process incoming messages here

}

};

Looper.loop();

}

}

这个时候我们可以通过在别的线程关联到LooperThread的looper并实例化Handler进行消息的发送.

* Use the provided {@link Looper} instead of the default one.

*

* @param looper The looper, must not be null.

*/

public Handler(Looper looper) {

this(looper, null, false);

}

那它的基本原理是什么呢?

我们先来看看prepare是怎么实现

private static void prepare(boolean quitAllowed) {

if (sThreadLocal.get() != null) {

throw new RuntimeException("Only one Looper may be created per thread");

}

sThreadLocal.set(new Looper(quitAllowed));

}

这里会去实例化一个Looper对象,放入sThreadLocal, sThreadLocal的声明是

static final ThreadLocal sThreadLocal = new ThreadLocal();

存放过程是

public void set(T value) {

Thread t = Thread.currentThread();

ThreadLocalMap map = getMap(t);

if (map != null)

map.set(this, value);

else

createMap(t, value);

}

这里可以看到,我们通过当前线程去获取Thread中

Thread {

//代码省略...

ThreadLocal.ThreadLocalMap threadLocals = null;

//代码省略...

}

通常来说第一次调用都是null,所以会走createMap(t, value)

void createMap(Thread t, T firstValue) {

t.threadLocals = new ThreadLocalMap(this, firstValue);

}

createMap直接就会创建ThreadLocalMap,并传入刚才的Looper对象,并放入到了线程的threadLocals中了.

这里需要说明一点是每个Thread都有一个 ThreadLocal.ThreadLocalMap threadLocals,它是一个独立的线程存储空间. 在消息循环机制中用来存放Looper对象. 大致模型图如下

image.png

接下来我们会在loop()中去启动消息循环机制

public static void loop() {

//代码省略...

final Looper me = myLooper();

final MessageQueue queue = me.mQueue;

for (;;) {

Message msg = queue.next(); // might block

msg.target.dispatchMessage(msg);

}

//代码省略...

}

这样就进入了一个循环,会不停的接收queue中的消息,并分发到Message中的target对象上,这里的target是发送消息的Handler.

我们可以看一个发送消息的例子

val handler = Handler()

handler.sendMessage(Message())

public final boolean sendMessage(Message msg)

{

return sendMessageDelayed(msg, 0);

}

public final boolean sendMessageDelayed(Message msg, long delayMillis)

{

if (delayMillis < 0) {

delayMillis = 0;

}

return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);

}

public boolean sendMessageAtTime(Message msg, long uptimeMillis) {

MessageQueue queue = mQueue;

if (queue == null) {

RuntimeException e = new RuntimeException(

this + " sendMessageAtTime() called with no mQueue");

Log.w("Looper", e.getMessage(), e);

return false;

}

return enqueueMessage(queue, msg, uptimeMillis);

}

private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {

msg.target = this;

if (mAsynchronous) {

msg.setAsynchronous(true);

}

return queue.enqueueMessage(msg, uptimeMillis);

}

这里msg.target = this实际上就是Handler对象,所以调用的msg.target.dispatchMessage(msg)实际上也是调用到的Handler的dispatchMessage

public void dispatchMessage(Message msg) {

if (msg.callback != null) {

handleCallback(msg);

} else {

if (mCallback != null) {

if (mCallback.handleMessage(msg)) {

return;

}

}

handleMessage(msg);

}

}

2,post和sendMessage区别

在使用Handler发送消息的过程中,通常会有两种调用方式,一种是post一个Runnable另外就是sendMessage, 这两种调用本质区别是什么呢. sendMessage调用实际上上面已经说过,最终会走到dispatchMessage的handleMessage处理消息,这里handleMessage有两种情况,一个是mCallback的handleMessage,mCallback是外部传入的Callback,通常实例化Handler的时候会传

val handler = Handler(Handler.Callback {

TODO("not implemented") //To change body of created functions use File | Settings | File Templates.

})

下面handleMessage(msg)就需要继承Handler进行handleMessage重写处理了.

下面来看看post的情况

public final boolean post(Runnable r)

{

return sendMessageDelayed(getPostMessage(r), 0);

}

private static Message getPostMessage(Runnable r) {

Message m = Message.obtain();

m.callback = r;

return m;

}

这里m.callback = r 实际上在dispatchMessage中就会调用

if (msg.callback != null) {

handleCallback(msg);

}

这里处理

private static void handleCallback(Message message) {

message.callback.run();

}

到这就会直接执行掉这个Runnable对象。所以结论就是,post是发送一个带有callback(实际上是Runnable对象),然后在接收消息的线程直接执行掉,而sendMessage是发送一个消息,接收消息的线程收到后会根据消息内容进行相应的处理逻辑.

android for 语句,Android中消息循环相关推荐

  1. Android 监听系统中消息通知事件

    0. 学习文章 参考了下面Blog 完全没有任何多余的代码 https://blog.csdn.net/wanghang1208/article/details/49905403 原来百度卫士的通知栏 ...

  2. matlab里脚本循环语句,Matlab中while循环语句的用

    Matlab 中while循环语句的用法? matlab while循环的用法.while循环的使用与for循环是类似的.但是其中还是有不少的区别,例如对于循环次数而言,while循环的次数是不定的, ...

  3. 窗口类的注册生成和消息循环

    1.一个项目只有一个子类继承cWinApp类,该子类也只有一个全局的对象,系统初始化时先运行 这个全局对象的构造函数及父类的构造函数 2.运行WinMain函数,调用AfxWinMain函数 3.运行 ...

  4. Python教学 | Python 中的循环结构(上)【附本文代码和数据】

    查看原文:[数据seminar]Python教学 | Python 中的循环结构(上)[附本文代码和数据] (qq.com) Part1引言 上期文章我们向大家介绍了 Python 程序控制结构中的分 ...

  5. android 结束if循环_Android Handler 消息循环机制

    前言 一问起Android应用程序的入口,很多人会说是Activity中的onCreate方法,也有人说是ActivityThread中的静态main方法.因为Java虚拟机在运行的时候会自动加载指定 ...

  6. android 消息循环机制--looper handler

    Looper类说明   Looper 类用来为一个线程跑一个消息循环. 线程在默认情况下是没有消息循环与之关联的,Thread类在run()方法中的内容执行完之后就退出了,即线程做完自己的工作之后就结 ...

  7. android自定义队列,Android 消息机制(一)消息队列的创建与循环的开始 Looper与MessageQueue...

    写在前面 本文基于Android 7.1.1 (API 25)的源码分析编写 与之前的触摸事件分发机制分析的文章一样,Android系统机制的分析中关键的一环就是事件消息的处理.之前也说过,Andro ...

  8. Android应用程序线程消息循环模型分析(5)

      从AsyncTask的实现可以看出,当我们第一次创建一个AsyncTask对象时,首先会执行下面静态初始化代码创建一个线程池sExecutor: private static final Bloc ...

  9. android return 如何跳出两个循环_关于不得不学的Android知识之消息机制

    概述 相信不管是出入Android,还是已开发多年的老司机们,肯定都对Android的Handler不会陌生,而它就是今天要介绍的Android消息机制中的一部分.在Android系统中,有两大特色利 ...

  10. Android应用程序线程消息循环模型分析

    出自:http://blog.csdn.net/luoshengyang/article/details/6905587 我们知道,Android应用程序是通过消息来驱动的,即在应用程序的主线程(UI ...

最新文章

  1. [vSphere培训实录]利用模板部署虚拟机时的一个小错误
  2. springboot + rabbitmq 用了消息确认机制,感觉掉坑里了
  3. [华为机试真题][2014]62.去除重复字符并排序
  4. 可心耳语-属于网络工程师的人声电台(第一期)
  5. 【设计模式】 桥梁模式
  6. 为子控件添加自定义绘图方式
  7. hihocoder 1183 割点和割边
  8. Java Server Page
  9. 5198.丑数III
  10. 基于Java的体育场地预约系统
  11. 1156 十个成绩排序
  12. 报错 AttributeError: ‘scipy.spatial.transform._rotation.Rotation‘ object has no attribute ‘as_dcm‘
  13. 办公台式计算机配置费用,原来这才是办公台式机需要的性能?
  14. php利用phpqrcode生成二维码,并将二维码盖在一张图上实现美化
  15. 这是初次的感觉 好象天空般晴朗
  16. TabLayout的使用和自定义红点消息提示
  17. uni-app里的拓展组件uni ui与UI框架uView UI的Popup 弹出层的区别!
  18. Altium designer实践总结
  19. 数据结构——约瑟夫环(Joseph Circle)
  20. 计算机ppt制作培训心得,中小学电脑制作活动培训心得体会范文

热门文章

  1. 【FPGA】TestBench中关于@eachvec
  2. 部署桌面虚拟化时要考虑的因素
  3. Linux无盘工作站的做法
  4. 七种程序员的基本技能
  5. git 多个stash选择指定的版本恢复
  6. 阿里高级技术专家:研发效能的追求永无止境 1
  7. 不依赖第三方环境和服务
  8. 《数值分析(原书第2版)》—— 1.5 不需要导数的根求解
  9. 深入理解JavaScript系列(25):设计模式之单例模式
  10. 工作的思考十:思维的高度决定设计的好坏(小菜的思维)