Android消息循环分析
我们的经常使用的系统中,程序的工作一般是有事件驱动和消息驱动两种方式,在Android系统中,Java应用程序是靠消息驱动来工作的。
消息驱动的原理就是:
1. 有一个消息队列。能够往这个队列中投递消息;
2. 有一个消息循环。不断从消息队列中取出消息。然后进行处理。
在Android中通过Looper来封装消息循环。同一时候在当中封装了一个消息队列MessageQueue。
另外Android给我们提供了一个封装类。来运行消息的投递,消息的处理,即Handler。
<!--more-->
在我们的线程中实现消息循环时,须要创建Looper,如:
class LooperThread extends Thread {
public Handler mHandler;
public void run() {
Looper.prepare(); //1.调用prepare
......
Looper.loop(); //2.进入消息循环
}
}
看上面的代码。事实上就是先准备Looper,然后进入消息循环。
1. 在prepare的时候。创建一个Looper。同一时候在Looper的构造方法中创建一个消息队列MessageQueue,同一时候将Looper保存到TLV中(这个是关于ThreadLocal的。不太懂。以后研究了再说)
2. 调用loop进入消息循环。此处事实上就是不断到MessageQueue中取消息Message。进行处理。
然后再看我们怎样借助Handler来发消息到队列和处理消息
Handler的成员(非所有):
final MessageQueue mQueue;
final Looper mLooper;
final Callback mCallback;
Message的成员(非所有):
Handler target;
Runnable callback;
能够看到Handler的成员包括Looper,通过查看源码,我们能够发现这个Looper是有两种方式获得的,1是在构造函数传进来。2是使用当前线程的Looper(假设当前线程无Looper,则会报错。我们在Activity中创建Handler不须要传Handler是由于Activity本身已经有一个Looper了),MessageQueue也就是Looper中的消息队列。
然后我们看怎么向消息队列发送消息。Handler有非常多方法发送队列(这个自己能够去查),比方我们看sendMessageDelayed(Message msg, long delayMillis)
public final boolean sendMessageDelayed(Message msg, long delayMillis) {
if (delayMillis < 0) {
delayMillis = 0;
}
return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
// SystemClock.uptimeMillis() 获取开机到如今的时间
}
//终于全部的消息是通过这个发。uptimeMillis是绝对时间(从开机那一秒算起)
public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
boolean sent = false;
MessageQueue queue = mQueue;
if (queue != null) {
msg.target = this;
sent = queue.enqueueMessage(msg, uptimeMillis);
}
return sent;
}
看上面的的代码。能够看到Handler将自己设为Message的target。然后然后将msg放到队列中,而且指定运行时间。
消息处理
处理消息,即Looper从MessageQueue中取出队列后,调用msg.target的dispatchMessage方法进行处理。此时会依照消息处理的优先级来处理:
1. 若msg本身有callback,则交其处理;
2. 若Handler有全局callback,则交由其处理;
3. 以上两种都没有,则交给Handler子类实现的handleMessage处理。此时须要重载handleMessage。
我们通常採用第三种方式进行处理。
注意!
!
!!我们通常是採用多线程,当创建Handler时,LooperThread中可能还未完毕Looper的创建,此时,Handler中无Looper,操作会报错。
我们能够採用Android为我们提供的HandlerThread来解决,该类已经创建了Looper,而且通过wait/notifyAll来避免错误的发生,降低我们反复造车的事情。我们创建该对象后。调用getLooper()就可以获得Looper(Looper未创建时会等待)。
补充
本文所属为Android中java层的消息循环机制,其在Native层还有消息循环。有单独的Looper。而且2.3以后MessageQueue的核心向Native层下移,native层java层均能够使用。这个我没有过多的研究了!哈哈
PS:本文參考《深入理解Android:卷I》
原文地址:http://blog.isming.me/blog/2014/04/02/android-message-loop-analyze/ 。转载请注明出处。
Android消息循环分析的更多相关文章
- Chromium on Android: Android在系统Chromium为了实现主消息循环分析
总结:刚开始接触一个Chromium on Android时间.很好奇Chromium主消息循环是如何整合Android应用. 为Android计划,一旦启动,主线程将具有Java消息层循环处理系统事 ...
- Android HandlerThread 消息循环机制之源代码解析
关于 HandlerThread 这个类.可能有些人眼睛一瞟,手指放在键盘上,然后就是一阵狂敲.立即就能敲出一段段华丽的代码: HandlerThread handlerThread = new Ha ...
- Android消息机制
每一个Android应用在启动的时候都会创建一个线程,这个线程被称为主线程或者UI线程,Android应用的所有操作默认都会运行在这个线程中. 但是当我们想要进行数据请求,图片下载,或者其他耗时操作时 ...
- Android的消息循环机制 Looper Handler类分析
Android的消息循环机制 Looper Handler类分析 Looper类说明 Looper 类用来为一个线程跑一个消息循环. 线程在默认情况下是没有消息循环与之关联的,Thread类在ru ...
- Android应用程序线程消息循环模型分析
文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6905587 我们知道,Android应用程序是 ...
- Android消息机制源码分析
本篇主要介绍Android中的消息机制,即Looper.Handler是如何协同工作的: Looper:主要用来管理当前线程的消息队列,每个线程只能有一个Looper Handler:用来将消息(Me ...
- [转]Handler MessageQueue Looper消息循环原理分析
Handler MessageQueue Looper消息循环原理分析 Handler概述 Handler在Android开发中非常重要,最常见的使用场景就是在子线程需要更新UI,用Handler ...
- [Android]简略的Android消息机制源码分析
相关源码 framework/base/core/java/andorid/os/Handler.java framework/base/core/java/andorid/os/Looper.jav ...
- 【转】Android开发实践:自定义带消息循环(Looper)的工作线程
http://ticktick.blog.51cto.com/823160/1565272 上一篇文章提到了Android系统的UI线程是一种带消息循环(Looper)机制的线程,同时Android也 ...
随机推荐
- codility上的问题(26) Hydrogenium 2013
题目,挺无聊的.一个裸的最短路.n个点,你住在0,要去买东西,每个点有一个关门时间,问能最早买到食物的时间.有两点注意 (1)有重边 (2) 原图是dicrect连接...但不是有向边,被这个误导了. ...
- 怎样获取浏览器上次的会话数据(session)
怎样获取浏览器上次的会话数据: 要知道上次会话session_id是多少? 让cookie保存的PHPSESSID的值不要浏览器一退出就被删除了? 所以我们要设置自己的session_id,不要系统自 ...
- UML看书笔记1:主体思想
对象设计需要解决的三大问题: 1.把“现实世界”映射到“对象世界” 2.从“对象世界”描述“现实世界” 3.验证“对象世界”是否反映了“现实世界” 现实世界与我们的对象世 ...
- Ch02 从零开始实例学习4
演练2-4 添加视图 原文链接:http://www.asp.net/mvc/tutorials/mvc-4/getting-started-with-aspnet-mvc4/adding-a-vi ...
- jQuery.mobile.changePage() | jQuery Mobile API Documentation
jQuery.mobile.changePage() | jQuery Mobile API Documentation <script> $.mobile.changePage( &qu ...
- Thymeleaf Javascript 取值
<script th:inline="javascript"> var openid = /*[[${session.wxuser.openId}]]*/ </s ...
- Linear Regression(线性回归)(三)—代价函数J(θ)选择的概率解释
(整理自AndrewNG的课件,转载请注明.整理者:华科小涛@http://www.cnblogs.com/hust-ghtao/) 在遇到线性回归问题时,我们总是令.可是我们为什么这样选择代价函数呢 ...
- Selenium HtmlUnitDriver 多浏览器的支持
1.HtmlUnitDriver WebDriver包括一个基于HtmlUnit的无界面实现,称为HtmlUnitDriver,即使用HtmlUnit时并不会打开真实的浏览器,而是在内存中执行代码,因 ...
- tomcat7 启动报错(转)
不加载任何自己的项目启动即报错: 严重: Error deploying web application directory D:\tomcat7.0.30\webapps\docs java.l ...
- HDU 4870 Rating (2014 多校联合第一场 J)(概率)
题意: 一个人有两个TC的账号,一开始两个账号rating都是0,然后每次它会选择里面rating较小的一个账号去打比赛,每次比赛有p的概率+1分,有1-p的概率-2分,当然如果本身是<=2分的 ...