Android HandlerThread案例詳解
HandlerThread 顧名思義就是一種可以使用 Handler 的 Thread。日常開發(fā)中我們經(jīng)常會(huì)通過創(chuàng)建一個(gè) Thread 去執(zhí)行任務(wù),有多個(gè)任務(wù)就多創(chuàng)建幾個(gè)線程實(shí)現(xiàn),這時(shí)候可能出現(xiàn)線程同步的問題。不過有時(shí)候我們并不需要很強(qiáng)的并發(fā)性,只需保證按照順序地執(zhí)行各個(gè)任務(wù)即可,有什么好辦法實(shí)現(xiàn)呢?第一反應(yīng)想到的可能是通過 Executors.newSingleThreadExecutor() 方法來創(chuàng)建一個(gè) SingleThreadExecutor,來統(tǒng)一所有的任務(wù)到一個(gè)線程中,然后按順序執(zhí)行。其實(shí),除了這個(gè)方法之外,HandlerThread 也可以實(shí)現(xiàn)。
簡單使用
首先創(chuàng)建一個(gè) HandlerThreadActivity
public class HandlerThreadActivity extends BaseActivity {
private static final String TAG = "HandlerThreadActivity";
private Button mStartBtn;
private Handler mHandler;
private HandlerThread mHandlerThread;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_handler_thread);
mStartBtn = findViewById(R.id.start_btn);
mHandlerThread = new HandlerThread("THREAD_NAME");
mHandlerThread.start();
mHandler = new Handler(mHandlerThread.getLooper());
mStartBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mHandler.post(new Runnable() {
@Override
public void run() {
Log.d(TAG, Thread.currentThread().getId() + " " + String.valueOf((Looper.myLooper() == Looper.getMainLooper())) + " 任務(wù):" + this.hashCode());
SystemClock.sleep(3000);
}
});
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
mHandlerThread.quit();
}
}
快速三擊按鈕,打印日志如下:

可以發(fā)現(xiàn),三次不同的任務(wù)按開始的順序執(zhí)行,而且是運(yùn)行在子線程中,那到底是怎么實(shí)現(xiàn)的呢?
源碼解析
public class HandlerThread extends Thread {
int mPriority;
int mTid = -1;
Looper mLooper;
private @Nullable Handler mHandler;
public HandlerThread(String name) {
super(name);
mPriority = Process.THREAD_PRIORITY_DEFAULT;
}
public HandlerThread(String name, int priority) {
super(name);
mPriority = priority;
}
protected void onLooperPrepared() {
}
@Override
public void run() {
// 獲取線程 id
mTid = Process.myTid();
//構(gòu)建一個(gè) Looper
Looper.prepare();
synchronized (this) {
mLooper = Looper.myLooper();
notifyAll();
}
//設(shè)置線程優(yōu)先級
Process.setThreadPriority(mPriority);
onLooperPrepared();
Looper.loop();
// Looper 循環(huán)
mTid = -1;
}
// 獲取當(dāng)前線程的 Looper,
public Looper getLooper() {
if (!isAlive()) {
return null;
}
synchronized (this) {
while (isAlive() && mLooper == null) {
try {
wait();
} catch (InterruptedException e) {
}
}
}
return mLooper;
}
/**
* @return a shared {@link Handler} associated with this thread
* @hide 方法隱藏掉,無法調(diào)用
*/
@NonNull
public Handler getThreadHandler() {
if (mHandler == null) {
mHandler = new Handler(getLooper());
}
return mHandler;
}
//線程退出方法,主要是調(diào)用 Looper.quit() 方法,不然一直在循環(huán)
public boolean quit() {
Looper looper = getLooper();
if (looper != null) {
looper.quit();
return true;
}
return false;
}
//同上,不過這個(gè)方法會(huì)把消息隊(duì)列中的已有消息處理完才會(huì)安全地退出
public boolean quitSafely() {
Looper looper = getLooper();
if (looper != null) {
looper.quitSafely();
return true;
}
return false;
}
public int getThreadId() {
return mTid;
}
}
通讀下來,如果熟悉 Handler 原理的同學(xué)大概就明白 HandlerThread 的機(jī)制了:
- HandlerThread 運(yùn)行 start() 方法,回調(diào) run() 方法。
- 在 run() 方法中通過 Looper.prepare() 來創(chuàng)建消息隊(duì)列,并通過 Looper.looper() 方法來開啟消息循環(huán)。
- 由于 Loop.loop() 是一個(gè)死循環(huán),導(dǎo)致 run() 也是無線循環(huán),因此當(dāng)我們不需要使用 HandlerThread 的時(shí)候,要調(diào)用它的 quit() 方法或者 quiteSafely() 方法。
到此這篇關(guān)于Android HandlerThread案例詳解的文章就介紹到這了,更多相關(guān)Android HandlerThread內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Android中BaseActivity自定義標(biāo)題欄
這篇文章主要介紹了Android中BaseActivity自定義標(biāo)題欄,非常實(shí)用,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-01-01
淺談Android硬件加速原理與實(shí)現(xiàn)簡介
這篇文章主要介紹了淺談Android硬件加速原理與實(shí)現(xiàn)簡介,本文嘗試從底層硬件原理,一直到上層代碼實(shí)現(xiàn),對硬件加速技術(shù)進(jìn)行簡單介紹,感興趣的小伙伴們可以參考一下2018-07-07
Android網(wǎng)絡(luò)數(shù)據(jù)開關(guān)用法簡單示例
這篇文章主要介紹了Android網(wǎng)絡(luò)數(shù)據(jù)開關(guān)用法,通過自定義函數(shù)調(diào)用系統(tǒng)服務(wù)實(shí)現(xiàn)開關(guān)功能,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2016-06-06
詳解Android使用OKHttp3實(shí)現(xiàn)下載(斷點(diǎn)續(xù)傳、顯示進(jìn)度)
本篇文章主要介紹了詳解Android使用OKHttp3實(shí)現(xiàn)下載(斷點(diǎn)續(xù)傳、顯示進(jìn)度),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-02-02
Android通過應(yīng)用程序創(chuàng)建快捷方式的方法
這篇文章主要介紹了Android通過應(yīng)用程序創(chuàng)建快捷方式的方法,涉及Android基于應(yīng)用程序創(chuàng)建快捷方式的圖標(biāo)及動(dòng)作等技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-09-09
Android提高之BLE開發(fā)Android手機(jī)搜索iBeacon基站
這篇文章主要介紹了BLE開發(fā)Android手機(jī)搜索iBeacon基站,需要的朋友可以參考下2014-08-08

