Welcome 微信登录
编程资源 图片资源库 蚂蚁家优选 PDF转换器

首页 / 操作系统 / Linux / Android开发实践:自定义带消息循环(Looper)的工作线程

上一篇文章提到了Android系统的UI线程是一种带消息循环(Looper)机制的线程(http://www.linuxidc.com/Linux/2014-12/110161.htm),同时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交流。相关附件下载地址:------------------------------------------分割线------------------------------------------免费下载地址在 http://linux.linuxidc.com/用户名与密码都是www.linuxidc.com具体下载目录在 /2014年资料/12月/4日/Android开发实践:自定义带消息循环(Looper)的工作线程下载方法见 http://www.linuxidc.com/Linux/2013-07/87684.htm------------------------------------------分割线------------------------------------------最简单的Ubuntu Touch & Android 双系统安装方式 http://www.linuxidc.com/Linux/2014-01/94881.htm在Nexus上实现Ubuntu和Android 4.4.2 双启动 http://www.linuxidc.com/Linux/2014-05/101849.htmUbuntu 14.04 配置 Android SDK 开发环境 http://www.linuxidc.com/Linux/2014-05/101039.htm64位Ubuntu 11.10下Android开发环境的搭建(JDK+Eclipse+ADT+Android SDK详细) http://www.linuxidc.com/Linux/2013-06/85303.htmUbuntu 14.04 x64配置Android 4.4 kitkat编译环境的方法 http://www.linuxidc.com/Linux/2014-04/101148.htmUbuntu 12.10 x64 安装 Android SDK http://www.linuxidc.com/Linux/2013-03/82005.htm更多Android相关信息见Android 专题页面 http://www.linuxidc.com/topicnews.aspx?tid=11本文永久更新链接地址:http://www.linuxidc.com/Linux/2014-12/110163.htm