【转】Android开发实践:自定义带消息循环(Looper)的工作线程
http://ticktick.blog.51cto.com/823160/1565272
上一篇文章提到了Android系统的UI线程是一种带消息循环(Looper)机制的线程,同时Android也提供了封装有消息循环(Looper)的HandlerThread类,这种线程,可以绑定Handler()对象,并通过Handler的sendMessage()函数向线程发送消息,通过handleMessage()函数,处理线程接收到的消息。这么说比较抽象,那么,本文就利用基础的Java类库,实现一个带消息循环(Looper)的线程,以帮助初学者理解这样一个Looper到底是怎么工作的。
1. 首先,我们完成一个简单的线程框架。
public class LooperThread {
private volatile boolean mIsLooperQuit = false;
private Thread mThread;
public void start() {
if( mThread != null ) {
return;
}
mIsLooperQuit = false;
mThread = new Thread(mLooperRunnable);
mThread.start();
}
public void stop() {
if( mThread == null ) {
return;
}
mIsLooperQuit = true;
mThread = null;
}
protected Runnable mLooperRunnable = new Runnable() {
@Override
public void run() {
while( !mIsLooperQuit ) {
}
}
};
}
如上述代码所示,mLooperRunnable.run()循环执行线程任务,mIsLooperQuit则是线程退出循环的条件。下面,我们将添加消息的发送和处理代码。
2. 添加线程循环的消息发送和处理代码
(1) 定义消息结构体,创建消息队列
public class LooperThread {
private Queue<Message> mMessageQueue = new LinkedList<Message>();
public static class Message {
int what;
}
}
(2) 创建互斥锁和条件变量
public class LooperThread {
private Lock mLock = new ReentrantLock();
private Condition mCondition = mLock.newCondition();
}
(3) 创建发送消息的函数
//发送消息,由外部其他模块调用,发送消息给线程
public void sendMessage( Message message ) {
if( mThread == null ) {
return;
}
mLock.lock();
mMessageQueue.add(message); //添加消息到消息队列
mCondition.signal(); //通知线程循环,有消息来了,请立即处理
mLock.unlock();
}
(4) 创建处理消息的函数
//处理消息,由线程内部调用
public void handleMessage(Message message) {
//这里可以通过一个Callback来回调监听者
}
(5) 在mLooperRunnable.run()循环中解析消息
protected Runnable mLooperRunnable = new Runnable() {
@Override
public void run() {
while( !mIsLooperQuit ) {
mLock.lock();
Message message = null;
try {
while( !mIsLooperQuit && mMessageQueue.isEmpty() ) {
mCondition.await(); //没有消息到来则休眠
}
message = mMessageQueue.poll();
}
catch (InterruptedException e) {
e.printStackTrace();
}
finally {
mLock.unlock();
}
handleMessage(message );
}
};
}
(6) 修改线程的Stop()函数,唤醒休眠的消息循环
public void stop() {
if( mThread == null ) {
return;
}
mIsLooperQuit = true;
mLock.lock();
mCondition.signal();
mLock.unlock();
mMessageQueue.clear();
mThread = null;
}
到这里,一个基本的带有消息循环的线程类封装就完成了,相信大家应该从编写这段代码的过程中,理解了系统是如何实现消息循环的。完整的代码见博文最后的附件,有任何疑问欢迎留言或者来信lujun.hust@gmail.com交流。
【转】Android开发实践:自定义带消息循环(Looper)的工作线程的更多相关文章
- android开发之自定义组件
android开发之自定义组件 一:自定义组件: 我认为,自定义组件就是android给我们提供的的一个空白的可以编辑的图片,它帮助我们实现的我们想要的界面,也就是通过自定义组件我们可以把我们要登入的 ...
- Android 开发实践 ViewGroup 实现左右滑出窗口(二)
接上一篇 <Android 开发实践 ViewGroup 实现左右滑出窗口(一)http://www.cnblogs.com/inkheart0124/p/3532862.html> 源码 ...
- Android 开发实践 ViewGroup 实现左右滑出窗口(一)
利用假期把以前做的东西总结整理一下,先从简单的开始吧.实现的效果是这样的: 做了个截屏动画,比例有点不对了,凑合着看吧. 整个窗口有3部分组成,中间的主界面是个列表,左边的滑出界面是个菜单,右边的 ...
- Xamarin.Android开发实践(二)
原文:Xamarin.Android开发实践(二) 一.准备 开始学习本教程前必须先完成该教程http://www.cnblogs.com/yaozhenfa/p/xamarin_android_qu ...
- Xamarin.Android开发实践(五)
原文:Xamarin.Android开发实践(五) 一.服务的生命周期 服务与活动一样,在它的整个生命周期中存在着一些事件,下图可以很好解释整个过程以及涉及到的方法: 在真实的使用中,Service来 ...
- Xamarin.Android开发实践(四)
原文:Xamarin.Android开发实践(四) Xamarin.Android下获取与解析JSON 一.新建项目 1.新建一个Android项目,并命名为为NetJsonList 2.右击引用,选 ...
- Xamarin.Android开发实践(三)
原文:Xamarin.Android开发实践(三) 一.前言 用过Android手机的人一定会发现一种现象,当你把一个应用置于后台后,一段时间之后在打开就会发现应用重新打开了,但是之前的相关的数据却没 ...
- Xamarin.Android开发实践(一)
原文:Xamarin.Android开发实践(一) 一.准备工作 1.创建一个空的解决方案,并命名为Phoneword 2.右击解决方案 新建->新建项目 并命名为Phoneword_Droid ...
- Android开发进阶——自定义View的使用及其原理探索
在Android开发中,系统提供给我们的UI控件是有限的,当我们需要使用一些特殊的控件的时候,只靠系统提供的控件,可能无法达到我们想要的效果,这时,就需要我们自定义一些控件,来完成我们想要的效果了.下 ...
随机推荐
- 树莓派 安装 php
执行如下命令(注意红色字部分是关键!) sudo apt-get install apache2 php5 libapache2-mod-php5 然后把网页文件复制到 /usr/www 中即可 参考 ...
- 平板与PC的文件交互及播放
发现在kindle上可以用ES开个浏览器,把FTP打开,实现文件的互访,之前还弄了一个大圈下了一大堆的垃圾软件, 而看电脑上的流媒体的话,则可以用dice播放器add一下samba就可以了
- 转:使用 JMeter 完成常用的压力测试
使用 JMeter 完成常用的压力测试 就目前 Java EE 的平台下开发的软件来说,这种节点通常可能是:Web 服务器.数据库服务器和 JMS 服务器.它们都是请求主要发生的地点,请求频率较其它的 ...
- [转]Linux的chattr与lsattr命令详解
转自:http://www.cnblogs.com/yangxia-test/archive/2013/05/24/3096410.html 这两个命令是用来查看和改变文件.目录属性的,与chmod这 ...
- PDF数据提取------2.相关类介绍
1.简介 构造数据类型PdfString封装Rect类,PdfAnalyzer类中定义一些PDF解析方法. 2.PdfString类与Rect类 public class PdfString : IC ...
- Linux 下部署单机 hadoop 测试
最终运行结果展示: 格式化namenode. 开始测试 显示测试进程 浏览器查看效果展示:(虽然还不清楚是什么意思,但是能看到这个效果已经很开心了) 话不多说,进入主题: 1. 安装 VMwareSt ...
- javascript注意点(1)
1.void运算符 ECMAScript 262规范,关于void说明如下: The void Operator The production UnaryExpression : void Unary ...
- kali install fcitx
1 卸载fcitx相关软件包 如果系统安装了fcitx相关东西,需要卸载,因为源的fcitx版本太低.请谨慎,后果自负. apt-get purge fcitx-* 2 手动下载最新的fcitx软件包 ...
- Office2016 转换零售版为VOL版
@echo off :ADMIN openfiles >nul >nul ||( echo Set UAC = CreateObject^("Shell.Application& ...
- (翻译)从底层了解ASP.NET体系结构 [转]
转自:http://www.cnblogs.com/rijing2004/archive/2007/09/14/howaspnetwork.html 前言 关于ASP.NET的底层的工作机制,最近园子 ...