【转】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控件是有限的,当我们需要使用一些特殊的控件的时候,只靠系统提供的控件,可能无法达到我们想要的效果,这时,就需要我们自定义一些控件,来完成我们想要的效果了.下 ...
随机推荐
- rsync同步时报“auth failed on module”错误的可能原因
关于这个auth失败的问题,有以下可能的情况: 1.密码输入错误: 请再次确认你登录用户的密码无误 2.secrets file格式错误: secrets file的文件格式是 upload ...
- RDoc
RDoc - Ruby Documentation System home github.com/rdoc/rdoc rdoc docs.seattlerb.org/rdoc bugs github. ...
- Android学习笔记--Sqlite数据库
前几天学习了Android中的数据存储,包括文件存储,SharedPreferences存储,还有就是Acndroid中的特色:SQLite数据库存储了.让我比较惊讶的是Android中竟然内嵌了一个 ...
- 【Mongo】MongoVUE的使用
我一直是在终端操作的mongo,各种update set remove insert,后来查了下有个叫mongoVUE的客户端,界面化比较方便操作吧~ 网上搜了下,说MongoVUE已经n年没有更新了 ...
- [转]Linux之od命令
转自:http://os.51cto.com/art/200912/173136.htm 随着计算机飞速的发展,很多人开始学习Linux,怎样才能学好Linux,一定要学好Linux的命令.学习Lin ...
- CMDB反思3
CMDB模型设计1 http://blog.vsharing.com/xqscool/A1274634.html 分类的问题上比较有感悟.在之前编写新版的CMDB模型的时候,曾将刀片机.x86服务器. ...
- jquery元素定位方法
用chrome浏览器打开页面,按f12调出开发者调试模式,查看elements,部分代码如下图所示,注意红框部分 假设我们要查找某些元素的位置,用鼠标移到那部分元素,调试器会自动用蓝颜色标示选中部分的 ...
- String - 兴趣解读
个优点: . 以下代码的HashCode是否相同,它们是否是同个对象: . 以下代码的HashCode是否相同,他们是否是同个对象: . 以下代码的HashCode是否相同,他们是否是同 ...
- Xcode集成Google Test
Xcode集成Google Test 1.下载源代码https://github.com/google/googletest 2.进入下载文件目录下googletest/make中运行make gte ...
- ajax 加载不同数据
<!doctype html> <html> <head> <meta charset="utf-8"> <title> ...