android for 语句,Android中消息循环
目录
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中消息循环相关推荐
- Android 监听系统中消息通知事件
0. 学习文章 参考了下面Blog 完全没有任何多余的代码 https://blog.csdn.net/wanghang1208/article/details/49905403 原来百度卫士的通知栏 ...
- matlab里脚本循环语句,Matlab中while循环语句的用
Matlab 中while循环语句的用法? matlab while循环的用法.while循环的使用与for循环是类似的.但是其中还是有不少的区别,例如对于循环次数而言,while循环的次数是不定的, ...
- 窗口类的注册生成和消息循环
1.一个项目只有一个子类继承cWinApp类,该子类也只有一个全局的对象,系统初始化时先运行 这个全局对象的构造函数及父类的构造函数 2.运行WinMain函数,调用AfxWinMain函数 3.运行 ...
- Python教学 | Python 中的循环结构(上)【附本文代码和数据】
查看原文:[数据seminar]Python教学 | Python 中的循环结构(上)[附本文代码和数据] (qq.com) Part1引言 上期文章我们向大家介绍了 Python 程序控制结构中的分 ...
- android 结束if循环_Android Handler 消息循环机制
前言 一问起Android应用程序的入口,很多人会说是Activity中的onCreate方法,也有人说是ActivityThread中的静态main方法.因为Java虚拟机在运行的时候会自动加载指定 ...
- android 消息循环机制--looper handler
Looper类说明 Looper 类用来为一个线程跑一个消息循环. 线程在默认情况下是没有消息循环与之关联的,Thread类在run()方法中的内容执行完之后就退出了,即线程做完自己的工作之后就结 ...
- android自定义队列,Android 消息机制(一)消息队列的创建与循环的开始 Looper与MessageQueue...
写在前面 本文基于Android 7.1.1 (API 25)的源码分析编写 与之前的触摸事件分发机制分析的文章一样,Android系统机制的分析中关键的一环就是事件消息的处理.之前也说过,Andro ...
- Android应用程序线程消息循环模型分析(5)
从AsyncTask的实现可以看出,当我们第一次创建一个AsyncTask对象时,首先会执行下面静态初始化代码创建一个线程池sExecutor: private static final Bloc ...
- android return 如何跳出两个循环_关于不得不学的Android知识之消息机制
概述 相信不管是出入Android,还是已开发多年的老司机们,肯定都对Android的Handler不会陌生,而它就是今天要介绍的Android消息机制中的一部分.在Android系统中,有两大特色利 ...
- Android应用程序线程消息循环模型分析
出自:http://blog.csdn.net/luoshengyang/article/details/6905587 我们知道,Android应用程序是通过消息来驱动的,即在应用程序的主线程(UI ...
最新文章
- [vSphere培训实录]利用模板部署虚拟机时的一个小错误
- springboot + rabbitmq 用了消息确认机制,感觉掉坑里了
- [华为机试真题][2014]62.去除重复字符并排序
- 可心耳语-属于网络工程师的人声电台(第一期)
- 【设计模式】 桥梁模式
- 为子控件添加自定义绘图方式
- hihocoder 1183 割点和割边
- Java Server Page
- 5198.丑数III
- 基于Java的体育场地预约系统
- 1156 十个成绩排序
- 报错 AttributeError: ‘scipy.spatial.transform._rotation.Rotation‘ object has no attribute ‘as_dcm‘
- 办公台式计算机配置费用,原来这才是办公台式机需要的性能?
- php利用phpqrcode生成二维码,并将二维码盖在一张图上实现美化
- 这是初次的感觉 好象天空般晴朗
- TabLayout的使用和自定义红点消息提示
- uni-app里的拓展组件uni ui与UI框架uView UI的Popup 弹出层的区别!
- Altium designer实践总结
- 数据结构——约瑟夫环(Joseph Circle)
- 计算机ppt制作培训心得,中小学电脑制作活动培训心得体会范文