說完了《Java中的多線程詳解》之后,今天來說一下Android中的多線程。
先來列舉下Android下啟用多線程的方式:
new Thread()
這個(gè)和Java中一樣,繼承Thread,或者實(shí)現(xiàn)Runnable接口,再用Runnable去實(shí)例化一個(gè)Thread對(duì)象。然后start新線程。
這種方法最簡單,但是也存在一些問題。
- 這只是起動(dòng)了一個(gè)新的線程,沒有任務(wù)的概念,不能做狀態(tài)的管理。start之后,run當(dāng)中的代碼就一定會(huì)執(zhí)行到底,無法中途取消。
- 如果從UI線程啟動(dòng),則該線程優(yōu)先級(jí)默認(rèn)為Default,歸于default cgroup,會(huì)平等的和UI線程爭奪CPU資源。
AsyncTask異步任務(wù)
- 線程優(yōu)先級(jí)為background,對(duì)UI線程的執(zhí)行影響極小。
- 中間流出了幾處回調(diào)都給了我們機(jī)會(huì)去中斷任務(wù)。
- 也存在一些問題,比如在不同的系統(tǒng)版本上串行與并行的執(zhí)行行為不一致。
HandlerThread
- HandlerThread本質(zhì)上就是一個(gè)普通Thread,只不過將Handler,Thread,Looper,MessageQueue幾個(gè)概念相結(jié)合。
- 采用隊(duì)列的形式,也就是串行。所以當(dāng)一個(gè)任務(wù)都將以隊(duì)列的方式逐個(gè)被執(zhí)行到,一旦隊(duì)列中有某個(gè)任務(wù)執(zhí)行時(shí)間過長,那么就會(huì)導(dǎo)致后續(xù)的任務(wù)都會(huì)被延遲處理。
- 可以處理多任務(wù),但是只有一個(gè)線程,所有的任務(wù)要排隊(duì)挨個(gè)執(zhí)行。
- HandlerThread的使用步驟:
①初始化一個(gè)HandlerThread
HandlerThread handlerThread = new HandlerThread("這里給線程起一個(gè)名字");
②啟動(dòng)handlerThread
handlerThread.start();
③在這個(gè)線程中創(chuàng)建一個(gè)handler對(duì)象
Handler handler = new Handler( myHandlerThread.getLooper() ){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
//這個(gè)方法是運(yùn)行在 handler-thread 線程中的 ,可以執(zhí)行耗時(shí)操作
Log.d( "handler " , "消息: " + msg.what + " 線程: " + Thread.currentThread().getName() ) ;
}
};
④給HandlerThread線程發(fā)消息,啟動(dòng)線程,可以在UI線程,也可以在子線程中發(fā)送。
//在主線程給handler發(fā)送消息
handler.sendEmptyMessage( 1 ) ;
new Thread(new Runnable() {
@Override
public void run() {
//在子線程給handler發(fā)送數(shù)據(jù)
handler.sendEmptyMessage( 2 ) ;
}
}).start() ;
⑤使用完畢后釋放資源
@Override
protected void onDestroy() {
super.onDestroy();
//釋放資源
myHandlerThread.quit() ;
}
IntentService
IntentService的實(shí)質(zhì)是new了一個(gè)HandlerThread來串行的處理Message Queue。只不過在所有的Message處理完畢之后,工作線程會(huì)自動(dòng)結(jié)束。所以可以把IntentService看做是Service和HandlerThread的結(jié)合體,適合需要在工作線程處理UI無關(guān)任務(wù)的場景。
ThreadPoolExecutor
- HandlerThread可以處理多任務(wù),但是是串行處理的。這里ThreadPoolExecutor可以并行處理多任務(wù)。
- 使用線程池可以避免線程的頻繁創(chuàng)建和銷毀。但同時(shí)也會(huì)讓代碼更加復(fù)雜,一旦出了問題,解決起來會(huì)更麻煩。