Android · 2014年11月17日 0

Android开发实践:自定义带消息循环(Looper)的工作线程

Android也提供了封装有消息循环(Looper)的HandlerThread类,这种线程,可以绑定Handler()对象,并通过 Handler的sendMessage()函数向线程发送消息,通过handleMessage()函数,处理线程接收到的消息。这么说比较抽象,那 么,本文就利用基础的Java类库,实现一个带消息循环(Looper)的线程,以帮助初学者理解这样一个Looper到底是怎么工作的。

 

1. 首先,我们完成一个简单的线程框架。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
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) 定义消息结构体,创建消息队列

 

1
2
3
4
5
6
7
8
public class LooperThread {
    private Queue<Message> mMessageQueue = new LinkedList<Message>();
    
    public static class Message {
        int what;
    }        
}

 

(2) 创建互斥锁和条件变量

 

1
2
3
4
5
public class LooperThread {
     private Lock mLock = new ReentrantLock();
     private Condition mCondition = mLock.newCondition();       
}

 

(3) 创建发送消息的函数

 

1
2
3
4
5
6
7
8
9
10
//发送消息,由外部其他模块调用,发送消息给线程
public void sendMessage( Message message ) {
    if( mThread == null ) {
        return;
    }      
    mLock.lock();
    mMessageQueue.add(message); //添加消息到消息队列
    mCondition.signal();        //通知线程循环,有消息来了,请立即处理
    mLock.unlock();
}

 

(4) 创建处理消息的函数

 

1
2
3
4
//处理消息,由线程内部调用
public void handleMessage(Message message) {
    //这里可以通过一个Callback来回调监听者
}

 

(5) 在mLooperRunnable.run()循环中解析消息

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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()函数,唤醒休眠的消息循环

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public void stop() {    
    if( mThread == null ) {
        return;
    }      
    mIsLooperQuit = true;
        
    mLock.lock();      
    mCondition.signal();
    mLock.unlock();
    
    mMessageQueue.clear();
    mThread = null;      
}

 

到这里,一个基本的带有消息循环的线程类封装就完成了,相信大家应该从编写这段代码的过程中,理解了系统是如何实现消息循环的

 

附近:LooperThread

转自:http://ticktick.blog.51cto.com/823160/1565272

 

Share this: