淘宝(阿里百川)手机客户端开发日记第九篇 Looper详解
public final class Looper;
官方的API:
Class used to run a message loop for a thread. Threads by default do not have a message loop associated with them; to create one, call prepare() in the thread that is to run the loop, and then loop() to have it process messages until the loop is stopped.
Most interaction with a message loop is through the Handler class.
这个类用来运行为一个在线程中消息循环,线程默认是不和消息循环关联的。为了创建在Thread中可以对消息循环,调用prepare() 函数在线程中,然后调用loop() 来处理消息直到循环停止。
大部分和消息循环交互是通过Handler 这个类。
官方给出的文档,说明的不是很详细,如果我们深入去理解它,我们只能去挖掘它的内部源代码来分析。应为android是开源的嘛!首先我们先看下Looper这个类的内部代码:
public class Looper {
private static final ThreadLocal sThreadLocal = new ThreadLocal();
//消息队列
final MessageQueue mQueue;
// 当前线程
Thread mThread; private Looper() { mQueue = new MessageQueue(); mThread = Thread.currentThread();
}
public static final void prepare() {
if (sThreadLocal.get() != null) {
throw new RuntimeException("Only one Looper may be created per thread");
} sThreadLocal.set(new Looper());
}
public static final Looper myLooper() { return (Looper)sThreadLocal.get(); }
public static final void loop() { Looper me = myLooper(); //得到当前线程Looper MessageQueue queue = me.mQueue; //得到当前looper对应的消息队列 Binder.clearCallingIdentity(); final long ident = Binder.clearCallingIdentity(); // 开始循环 while (true) { Message msg = queue.next(); if (msg != null) { if (msg.target == null) { // message的target为0,结束循环 return; } msg.target.dispatchMessage(msg); // 将消息交由message的target(其实就是handler)处理 msg.recycle(); } } } public void quit() { // 结束循环消息 Message msg = Message.obtain(); mQueue.enqueueMessage(msg, 0); } }
public class Handler {
final MessageQueue mQueue; final Looper mLooper; final Callback mCallback; //回调
public Handler() { mLooper = Looper.myLooper(); if (mLooper == null) { throw new RuntimeException( "Can't create handler inside thread that has not called Looper.prepare()"); } mQueue = mLooper.mQueue; mCallback = null; } public final boolean post(Runnable r) { return sendMessageDelayed(getPostMessage(r), 0); //立即执行 }
private final Message getPostMessage(Runnable r) { Message m = Message.obtain(); m.callback = r; return m; }
public boolean sendMessageAtTime(Message msg, long uptimeMillis) { boolean sent = false; MessageQueue queue = mQueue; if (queue != null) { msg.target = this; sent = queue.enqueueMessage(msg, uptimeMillis); } else { RuntimeException e = new RuntimeException( this + " sendMessageAtTime() called with no mQueue"); Log.w("Looper", e.getMessage(), e); } return sent; }
public void dispatchMessage(Message msg) { if (msg.callback != null) { handleCallback(msg); } else { if (mCallback != null) { if (mCallback.handleMessage(msg)) { return; } } handleMessage(msg); } } private final void handleCallback(Message message) { message.callback.run(); //执行线程run方法 }
public void handleMessage(Message msg) { //处理消息,由客户端自己去实现调用 }
}
我们从Looper类,和Handler类的源代码,得到很多一些重要的结论:
Looper自己有一个消息队列,这个消息的添加由Handler来发送,然后,Looper自己不断的循环,取出消息,再有Handler的handleMessage方法来处理,但是handleMessage这个方法,是一个空实现,由程序员根据自己的业务逻辑来对消息进行处理。
Looper在android中被广泛的使用到;比如,在一个Activity里,大家知道activity 其实就是一个UI线程,在activity创建期间,它也创建了消息队列和消息循环Looper。这个大家可以到ActivityThread.java中能够找到对应的信息。
转载请注明http://www.cnblogs.com/yushengbo,否则将追究版权责任!
淘宝(阿里百川)手机客户端开发日记第九篇 Looper详解的更多相关文章
- 淘宝(阿里百川)手机客户端开发日记第一篇 android 主框架搭建(一)
android 主框架搭建(一) 1.开发环境:Android Studio 相继点击下一步,直接项目建立完毕(如下图) 图片看的效果如果很小,请放大您的浏览器显示百分比 转载请注明http://w ...
- 淘宝(阿里百川)手机客户端开发日记第二篇 android首页之顶部轮播特效制作 (二)
1.我们来设计flash_slide.xml 布局,这个xml主要做成模块化,方便其它的activity可以动态去调用. flash_slide.xml内容如下: <?xml version=& ...
- 淘宝(阿里百川)手机客户端开发日记第十五篇 JSON解析(四)
解析一个从淘宝传递的JSON (大家如有兴趣可以测试下):{ "tae_item_detail_get_response": { "data": { " ...
- 淘宝(阿里百川)手机客户端开发日记第十二篇 mysql的认识
我这里用的是wamp,大家可以到网上去下载对应的包,自行安装,对于程序员来讲,安装软件大部分都应该不是问题的,所以我不去将具体安装的方法. wamp安装好后,在我们屏幕的右下角, 这样的图标,我们右键 ...
- 淘宝(阿里百川)手机客户端开发日记第十一篇 JSP+Servlet
由于本人从事.net开发已有多年经验,今天由于工作需要,我只能学习下JSP+Servlet,至于java web提供了更好的开发框架MVC,现在由于时间关系,我只好用JSP+Servlet来搭建服务器 ...
- 淘宝(阿里百川)手机客户端开发日记第十四篇 jsp提交含有上传控件表单乱码问题
今天我来总结昨天开发的一个简单的jsp web 应用程序时,在做一个调教表单,从servlet端获取数据,这个表单里含有上传文件控件.如果我们在测试的时候,获取数据的是乱码,这时,大家可以先去掉上传控 ...
- 淘宝(阿里百川)手机客户端开发日记第五篇 SharedPreferences使用详解
我们知道,Android中数据存储技术由于如下几种 1 使用SharedPreferences存储数据 2 文件存储数据 3 SQLite数据库存储数据 4 使用ContentProvider存储数据 ...
- 淘宝(阿里百川)手机客户端开发日记第十篇 阿里百川服务器环境介绍之API文档的快速链接(四)
个人感觉比较重要的快速链接: http://open.taobao.com/doc/detail.htm?id=102513 http://open.taobao.com/doc/detail.htm ...
- 淘宝(阿里百川)手机客户端开发日记第十三篇 mysql的连接
首先,我建立了一个包,里面存放了三个类文件,这三个文件是我从网络中找的,经过自己的整理.(我刚才查找想把这三个文件传上去,可能是自己对cnblogs的博客不太熟悉吧,没有找到,我只好粘贴代码了) 三个 ...
随机推荐
- replace 替换全部的正确姿势
本文同步自我的个人博客:http://www.52cik.com/2015/11/06/replace-all.html 关于字符串替换问题,其实是个很简单的问题,但却也不那么简单,至少对于很多新手而 ...
- 怎样写 OpenStack Neutron 的 Extension (二)
接着之前一篇文章,再来谈谈 Extension 的具体实现问题.我使用的是本地数据库加远程API调用的方法,所以先要定义一下数据库中 myextension 如何存储.首先,我们可以在自己的 plug ...
- 使用TinkPHP实现品字形布局
一.后台管理模版 后台管理模版通常使用frameset/iframe来布局.例如: <!DOCTYPE html> <html> <head> <title& ...
- 2、面向对象以及winform的简单运用(面向对象的四大基本特性)
面向对象的四大基本特性 面向对象的核心概念就是封装.抽象.继承.多态这四大基本特性,在这里先解释一下它们的定义: 封装:是一种隐藏信息的特性.找到变化并且把它封装起来,你就可以在不影响其它部分的情况下 ...
- Daily Scrum – 1/15
Meeting Minutes 确定了user course 的方案. 完成了屏幕的自适应: 安排了最后几天的日程 Burndown Progress part 组员 今日工作 Time ...
- NumberFormat类的用法
NumberFormat.getInstance()方法返回NumberFormat的一个实例(实际上是NumberFormat具体的一个子类,例如DecimalFormat), 这适合根据本地设置格 ...
- MVC学习Day02之校验
MVC校验有两种方法: 方法一:自己动手写js---------略 方法二: l在View的页面中,首先指定页面强类型@model 类型 l使用Html.***For(model=>model. ...
- WDCP(WDlinux Control Panel) mysql/add_user.php、mysql/add_db.php Authentication Loss
目录 . 漏洞描述 . 漏洞触发条件 . 漏洞影响范围 . 漏洞代码分析 . 防御方法 . 攻防思考 1. 漏洞描述 http://www.wooyun.org/bugs/wooyun-2010-06 ...
- Linux System Log Collection、Log Integration、Log Analysis System Building Learning
目录 . 为什么要构建日志系统 . 通用日志系统的总体架构 . 日志系统的元数据来源:data source . 日志系统的子安全域日志收集系统:client Agent . 日志系统的中心日志整合系 ...
- 微型 ORM-FluentData 温故知新系列
http://www.cnblogs.com/_popc/archive/2012/12/26/2834726.html 引言:FluentData 是微型 ORM(micro-ORM)家族的一名新成 ...