上一篇文章提到了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 mMessageQueue = new LinkedList();        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交流,或者关注我的新浪微博 @卢_俊 获取最新的文章和资讯。


更多相关文章

  1. android - 为响应度而设计 - 开发文档翻译
  2. Android中AsyncTask的简单用法
  3. Android中线程形态AsyncTask、HandlerThread 和 IntentService简
  4. Android简明开发教程十九:线程 Bezier曲线
  5. android中使用线程池和临时缓存优化网络图片加载
  6. Android多线程:理解和简单使用总结
  7. Android(安卓)GLES多线程处理
  8. android:handler
  9. Android(安卓)Handler

随机推荐

  1. 学了那么多公式,却依旧用不好Excel(实例讲
  2. 「图解」缺失的第一个正数
  3. 经验分享:谈谈“面试”
  4. Excel预测工作表
  5. 谷歌浏览器团队:感谢 Flash 所做的一切
  6. 动态规划之空间优化与总结回顾
  7. 万字长文!动态规划的终极难题:字符匹配类
  8. Excel数据处理(缺失值/重复值/异常值/拆分
  9. 超详细!详解一道高频算法题:括号生成
  10. 苹果拒绝支持PWA的行为对Web贻害无穷!