您好,登錄后才能下訂單哦!
上一篇文章提到了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交流,或者關注我的新浪微博 @盧_俊 獲取最新的文章和資訊。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。