Android 線程之自定義帶消息循環(huán)Looper的實(shí)例
Android 線程之自定義帶消息循環(huán)Looper的實(shí)例
Android系統(tǒng)的UI線程是一種帶消息循環(huán)(Looper)機(jī)制的線程,同時(shí)Android也提供了封裝有消息循環(huán)(Looper)的HandlerThread類(lèi),這種線程,可以綁定Handler()對(duì)象,并通過(guò)Handler的sendMessage()函數(shù)向線程發(fā)送消息,通過(guò)handleMessage()函數(shù),處理線程接收到的消息。這么說(shuō)比較抽象,那么,本文就利用基礎(chǔ)的Java類(lèi)庫(kù),實(shí)現(xiàn)一個(gè)帶消息循環(huán)(Looper)的線程,以幫助初學(xué)者理解這樣一個(gè)Looper到底是怎么工作的。
1. 首先,我們完成一個(gè)簡(jiǎn)單的線程框架。
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()循環(huán)執(zhí)行線程任務(wù),mIsLooperQuit則是線程退出循環(huán)的條件。下面,我們將添加消息的發(fā)送和處理代碼。
2. 添加線程循環(huán)的消息發(fā)送和處理代碼
(1) 定義消息結(jié)構(gòu)體,創(chuàng)建消息隊(duì)列
public class LooperThread {
private Queue<Message> mMessageQueue = new LinkedList<Message>();
public static class Message {
int what;
}
}
(2) 創(chuàng)建互斥鎖和條件變量
public class LooperThread {
private Lock mLock = new ReentrantLock();
private Condition mCondition = mLock.newCondition();
}
(3) 創(chuàng)建發(fā)送消息的函數(shù)
//發(fā)送消息,由外部其他模塊調(diào)用,發(fā)送消息給線程
public void sendMessage( Message message ) {
if( mThread == null ) {
return;
}
mLock.lock();
mMessageQueue.add(message); //添加消息到消息隊(duì)列
mCondition.signal(); //通知線程循環(huán),有消息來(lái)了,請(qǐng)立即處理
mLock.unlock();
}
(4) 創(chuàng)建處理消息的函數(shù)
//處理消息,由線程內(nèi)部調(diào)用
public void handleMessage(Message message) {
//這里可以通過(guò)一個(gè)Callback來(lái)回調(diào)監(jiān)聽(tīng)者
}
(5) 在mLooperRunnable.run()循環(huán)中解析消息
protected Runnable mLooperRunnable = new Runnable() {
@Override
public void run() {
while( !mIsLooperQuit ) {
mLock.lock();
Message message = null;
try {
while( !mIsLooperQuit && mMessageQueue.isEmpty() ) {
mCondition.await(); //沒(méi)有消息到來(lái)則休眠
}
message = mMessageQueue.poll();
}
catch (InterruptedException e) {
e.printStackTrace();
}
finally {
mLock.unlock();
}
handleMessage(message );
}
};
}
(6) 修改線程的Stop()函數(shù),喚醒休眠的消息循環(huán)
public void stop() {
if( mThread == null ) {
return;
}
mIsLooperQuit = true;
mLock.lock();
mCondition.signal();
mLock.unlock();
mMessageQueue.clear();
mThread = null;
}
到這里,一個(gè)基本的帶有消息循環(huán)的線程類(lèi)封裝就完成了,相信大家應(yīng)該從編寫(xiě)這段代碼的過(guò)程中,理解了系統(tǒng)是如何實(shí)現(xiàn)消息循環(huán)的。
如有疑問(wèn)請(qǐng)留言或者到本站社區(qū)交流討論,感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!
相關(guān)文章
Flutter配置代理抓包實(shí)現(xiàn)過(guò)程詳解
這篇文章主要為大家介紹了Flutter配置代理抓包實(shí)現(xiàn)過(guò)程詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-02-02
Flutter利用ORM框架簡(jiǎn)化本地?cái)?shù)據(jù)庫(kù)管理詳解
使用?sqflite?相對(duì)來(lái)說(shuō)還是有點(diǎn)復(fù)雜,比如遇到數(shù)據(jù)不兼容的時(shí)候需要手動(dòng)轉(zhuǎn)換,增加了不少繁瑣的代碼。本篇我們就來(lái)介紹一個(gè)?ORM?框架,來(lái)簡(jiǎn)化數(shù)據(jù)庫(kù)的管理,感興趣的可以了解一下2023-04-04
Flutter onTap中讓你脫穎而出的5條規(guī)則
這篇文章主要為大家介紹了Flutter onTap中讓你脫穎而出的5條規(guī)則,小事情決定了你的熟練程度,這些小細(xì)節(jié)的有趣之處在于它們的豐富性2023-11-11
Android compose氣泡升起和水滴下墜動(dòng)畫(huà)實(shí)現(xiàn)示例
這篇文章主要為大家介紹了Android compose氣泡升起和水滴下墜動(dòng)畫(huà)實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01
Android實(shí)現(xiàn)可拖拽的GridView效果長(zhǎng)按可拖拽刪除數(shù)據(jù)源
這篇文章主要介紹了Android實(shí)現(xiàn)可拖拽的GridView效果長(zhǎng)按可拖拽刪除數(shù)據(jù)源,要實(shí)現(xiàn)的基本功能是長(zhǎng)按,移到垃圾桶,刪除數(shù)據(jù),需要的朋友可以參考下2017-12-12
Android自定義鍵盤(pán)的實(shí)現(xiàn)(數(shù)字鍵盤(pán)和字母鍵盤(pán))
本篇文章主要介紹了Android自定義鍵盤(pán)的實(shí)現(xiàn)(數(shù)字鍵盤(pán)和字母鍵盤(pán)),具有一定的參考價(jià)值,有興趣的可以了解一下2017-08-08
Android?Flutter實(shí)現(xiàn)任意拖動(dòng)的控件
使用flutter開(kāi)發(fā)是需要控件能拖動(dòng),比如畫(huà)板中的元素,或者工具條等,所以本文為大家準(zhǔn)備了Flutter實(shí)現(xiàn)任意拖動(dòng)控件的示例代碼,希望對(duì)大家有所幫助2023-07-07
Android設(shè)置TextView顯示指定個(gè)數(shù)字符,超過(guò)部分顯示...(省略號(hào))的方法
這篇文章主要介紹了Android設(shè)置TextView顯示指定個(gè)數(shù)字符,超過(guò)部分顯示...(省略號(hào))的方法,涉及Android TextView屬性設(shè)置的相關(guān)技巧,需要的朋友可以參考下2016-02-02

