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)的工作线程的更多相关文章

  1. android开发之自定义组件

    android开发之自定义组件 一:自定义组件: 我认为,自定义组件就是android给我们提供的的一个空白的可以编辑的图片,它帮助我们实现的我们想要的界面,也就是通过自定义组件我们可以把我们要登入的 ...

  2. Android 开发实践 ViewGroup 实现左右滑出窗口(二)

    接上一篇 <Android 开发实践 ViewGroup 实现左右滑出窗口(一)http://www.cnblogs.com/inkheart0124/p/3532862.html> 源码 ...

  3. Android 开发实践 ViewGroup 实现左右滑出窗口(一)

    利用假期把以前做的东西总结整理一下,先从简单的开始吧.实现的效果是这样的:   做了个截屏动画,比例有点不对了,凑合着看吧. 整个窗口有3部分组成,中间的主界面是个列表,左边的滑出界面是个菜单,右边的 ...

  4. Xamarin.Android开发实践(二)

    原文:Xamarin.Android开发实践(二) 一.准备 开始学习本教程前必须先完成该教程http://www.cnblogs.com/yaozhenfa/p/xamarin_android_qu ...

  5. Xamarin.Android开发实践(五)

    原文:Xamarin.Android开发实践(五) 一.服务的生命周期 服务与活动一样,在它的整个生命周期中存在着一些事件,下图可以很好解释整个过程以及涉及到的方法: 在真实的使用中,Service来 ...

  6. Xamarin.Android开发实践(四)

    原文:Xamarin.Android开发实践(四) Xamarin.Android下获取与解析JSON 一.新建项目 1.新建一个Android项目,并命名为为NetJsonList 2.右击引用,选 ...

  7. Xamarin.Android开发实践(三)

    原文:Xamarin.Android开发实践(三) 一.前言 用过Android手机的人一定会发现一种现象,当你把一个应用置于后台后,一段时间之后在打开就会发现应用重新打开了,但是之前的相关的数据却没 ...

  8. Xamarin.Android开发实践(一)

    原文:Xamarin.Android开发实践(一) 一.准备工作 1.创建一个空的解决方案,并命名为Phoneword 2.右击解决方案 新建->新建项目 并命名为Phoneword_Droid ...

  9. Android开发进阶——自定义View的使用及其原理探索

    在Android开发中,系统提供给我们的UI控件是有限的,当我们需要使用一些特殊的控件的时候,只靠系统提供的控件,可能无法达到我们想要的效果,这时,就需要我们自定义一些控件,来完成我们想要的效果了.下 ...

随机推荐

  1. MySQL与Oracle 差异比较之七其它

    其它 编号 类别 ORACLE MYSQL 注释 1 内连接的更改 1.select a.*, b.*, c.*, d.*  from a, b, c, d where a.id = b.id   a ...

  2. windows7操作系统64位安装ArcSDE10.1和Oracle11g

    安装环境如下: Oracle11g R2 64位服务端Oracle11g R2 32位客户端(管理员,第二项)ArcSDE10.1 for Oracle11g SDE数据库可由其它机器安装Arcata ...

  3. Nginx工作原理和优化、漏洞

    1.  Nginx的模块与工作原理 第三方模块:HTTP Upstream Request Hash模块.Notice模块和HTTP Access Key模块. 图1-1展示了Nginx模块常规的HT ...

  4. SSD Cloud Hosting–Linode-Mysql数据库的安装与配置

    接着上一篇的话题:SSD Cloud Hosting - Linode的配置和部署,搭建Java环境 8.Mysql数据库的安装与配置 安装 检查yum里边有没有mysql: yum list|gre ...

  5. 组建自动化工具Ant

    组建自动化工具Ant Ant可以帮助我们自动化的完成项目的构建 下面是维基百科对Ant的介绍:http://zh.wikipedia.org/wiki/Apache_Ant Apache Ant,是一 ...

  6. 【JNI】OPUS压缩与解压的JNI调用(.DLL版本)

    OPUS压缩与解压的JNI调用(.DLL版本) 一.写在开头: 理论上讲,这是我在博客园的第一篇原创的博客,之前也一直想找个地方写点东西,把最近做的一些东西归纳总结下,但是一般工程做完了一高兴就把东西 ...

  7. 自学Java过程

    由于之前判断失误,其实也不应该说失误吧,自己脱产花了几个月来啃C,现在基本上算是啃完了吧,之所以说失误是因为:没有找到跟C有关的适合我的工作!!! 本来的打算是先把基础搞定然后去找找看有没有肯收留打杂 ...

  8. C#缓存的一点想法及测试

    项目开发中,用到了缓存,其中的一个列表项,可能要多线程处理,就有了下面的想法,具体的问题在代码中有详细说明,见下文. static void Main(string[] args) { 测试缓存的想法 ...

  9. <javascript搞基程序设计>笔记2015-9-25

    1.一元加减 var a=28; alert(--a); //27,先减后用 alert(a--); //27,先用后减 alert(a); //26, 2.位操作符 按位非(NOT):按位取反:符号 ...

  10. C# 必应代码搜索

    微软宣布推出必应代码搜索服务,暂时只支持 C# 语言,日后将支持更多代码语言. Visual Studio 用户安装必应搜索插件之后可使用该服务来简化编程任务.Visual Studio 与 MSDN ...