HandlerThread學習

HandlerThread 是一個封裝好的looper線程類尝蠕。

從源碼看看
public class HandlerThread extends Thread {
int mPriority; // 線程優(yōu)先級
int mTid = -1; // 修改線程優(yōu)先級片任、調(diào)度策略時用來做線程唯一標識
Looper mLooper; // 與線程關聯(lián)的Looper

public HandlerThread(String name) {
    super(name);
    mPriority = Process.THREAD_PRIORITY_DEFAULT; // 設置默認優(yōu)先級0
}

public HandlerThread(String name, int priority) {
    super(name);
    mPriority = priority;                        // 主動設置優(yōu)先級
}

protected void onLooperPrepared() { //回調(diào)方法,looper開始前執(zhí)行
}

@Override
public void run() {
mTid = Process.myTid();
Looper.prepare(); // 初始化一個Looper對象望伦,然后存入到ThreadLocal中,將Looper和當前線成進行綁定,一一對應.
synchronized (this) { // 進入同步塊
mLooper = Looper.myLooper(); //得到當前線程的looper對象
notifyAll();//通知其他線程
}
Process.setThreadPriority(mPriority); // 設置線程優(yōu)先級
onLooperPrepared(); // 回調(diào)重寫
Looper.loop(); // 一個死循環(huán)粒竖,不斷從MessageQueue取出消息氧骤,如有消息就處理呻疹,沒有就阻塞
mTid = -1; // 因為Looper.loop()是個死循環(huán)啊,執(zhí)行到mTid = -1的時候筹陵,就是looper退出的時候
}

public Looper getLooper() {
    if (!isAlive()) { // 如果線程不是在存活狀態(tài)則直接返回null刽锤。
        return null;
    }
    
    synchronized (this) {
        while (isAlive() && mLooper == null) { // 進入同步塊镊尺,當條件不滿足時無限等待,
            try {                              // 直到mLooper被設置成有效值了才退出等待
                wait();                        // run方法里的notifyAll就是用來喚醒這里的
            } catch (InterruptedException e) { // 中斷異常
            }
        }
    }
    return mLooper; // 最后返回mLooper
}


public boolean quit() {
    Looper looper = getLooper();
    if (looper != null) {
        looper.quit();
        return true;
    }
    return false;
}

public boolean quitSafely() {
    Looper looper = getLooper();
    if (looper != null) {
        looper.quitSafely();
        return true;
    }
    return false;
}

void quit(boolean safe) {
if (!mQuitAllowed) {
throw new IllegalStateException("Main thread not allowed to quit.");
}

    synchronized (this) {
        if (mQuitting) {
            return;
        }
        mQuitting = true;

        if (safe) {
            removeAllFutureMessagesLocked();
        } else {
            removeAllMessagesLocked();
        }

        // We can assume mPtr != 0 because mQuitting was previously false.
        nativeWake(mPtr);
    }

}

quit()和 quitSafely()的區(qū)別:
removeAllMessagesLocked()是把MessageQueue消息池中所有的消息全部清空并思,無論延遲與否
removeAllFutureMessagesLocked()是只清空延遲消息庐氮,非延遲消息派發(fā)出去讓Handler去處理。

異步handler的創(chuàng)建方式
Thread newThread = new Thread(new Runnable()
{
@Override
public void run() {
Looper.prepare();
Looper.loop();
}
});
newThread.start();
Handler handler = new Handler(newThread.getLooper());

當執(zhí)行到Handler handler = new Handler(newThread.getLooper());的時候宋彼,newThread的looper可能還沒有創(chuàng)建好弄砍,會有線程同步的
問題。

總結:
1.不管調(diào)用哪個输涕,Looper就不再接收新的消息音婶,再通過Handler調(diào)用sendMessage發(fā)消息都只會返回false,Looper的quit方法從API Level 1就存在了莱坎,但是Looper的quitSafely方法從API Level 18才添加進來

2.HandlerThread本質(zhì)是一個Thread衣式,區(qū)別在于他在run()之后創(chuàng)建了一個含有消息隊列的Looper,這樣我們在子線程中創(chuàng)建Handler時候只需指定使用HandlerThread中的Looper檐什,不用再調(diào)用Looper.prepare(),looper.loop()碴卧,并且做了同步的處理,簡化了操作乃正。

3.另外Handler與Activity在同一個線程中螟深,不能做耗時操作。HandlerThread是新的線程烫葬,可做耗時操作

舉例:
public class MainActivity extends Activity {

private Handler handlerthread;
private HandlerThread thread;

//創(chuàng)建主線程中的handler
private Handler handler = new Handler() {
    public void handleMessage(android.os.Message msg) {
        Message message = new Message();
        handlerthread.sendMessageDelayed(message, 1000);
        Log.d("wuc", "主線程");
    }
};

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    Button bt_test = (Button)findViewById(R.id.bt_test);
    bt_test.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            handlerthread.sendEmptyMessage(1);
        }
    });

    thread = new HandlerThread("threadHandler");
    thread.start();
    handlerthread = new Handler(thread.getLooper()){
        @Override
        public void handleMessage(Message msg) {
            Message message = new Message();
            //handler每隔1秒向主線程發(fā)送一次消息界弧。
            Log.d("wuc", "子線程");
            handler.sendMessageDelayed(message, 1000);
        }
    };
}

}

04-26 16:49:26.822 7349-7385/com.example.lyf.androidtext D/wuc: 子線程
04-26 16:49:27.822 7349-7349/com.example.lyf.androidtext D/wuc: 主線程
04-26 16:49:28.823 7349-7385/com.example.lyf.androidtext D/wuc: 子線程
04-26 16:49:29.826 7349-7349/com.example.lyf.androidtext D/wuc: 主線程
04-26 16:49:30.826 7349-7385/com.example.lyf.androidtext D/wuc: 子線程
04-26 16:49:31.827 7349-7349/com.example.lyf.androidtext D/wuc: 主線程
04-26 16:49:32.828 7349-7385/com.example.lyf.androidtext D/wuc: 子線程

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市搭综,隨后出現(xiàn)的幾起案子垢箕,更是在濱河造成了極大的恐慌,老刑警劉巖兑巾,帶你破解...
    沈念sama閱讀 211,194評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件条获,死亡現(xiàn)場離奇詭異,居然都是意外死亡蒋歌,警方通過查閱死者的電腦和手機帅掘,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評論 2 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來堂油,“玉大人修档,你說我怎么就攤上這事「颍” “怎么了吱窝?”我有些...
    開封第一講書人閱讀 156,780評論 0 346
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我院峡,道長兴使,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,388評論 1 283
  • 正文 為了忘掉前任照激,我火速辦了婚禮发魄,結果婚禮上,老公的妹妹穿的比我還像新娘俩垃。我一直安慰自己欠母,他們只是感情好,可當我...
    茶點故事閱讀 65,430評論 5 384
  • 文/花漫 我一把揭開白布吆寨。 她就那樣靜靜地躺著赏淌,像睡著了一般。 火紅的嫁衣襯著肌膚如雪啄清。 梳的紋絲不亂的頭發(fā)上六水,一...
    開封第一講書人閱讀 49,764評論 1 290
  • 那天,我揣著相機與錄音辣卒,去河邊找鬼掷贾。 笑死,一個胖子當著我的面吹牛荣茫,可吹牛的內(nèi)容都是我干的想帅。 我是一名探鬼主播,決...
    沈念sama閱讀 38,907評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼啡莉,長吁一口氣:“原來是場噩夢啊……” “哼港准!你這毒婦竟也來了?” 一聲冷哼從身側響起咧欣,我...
    開封第一講書人閱讀 37,679評論 0 266
  • 序言:老撾萬榮一對情侶失蹤浅缸,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后魄咕,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體衩椒,經(jīng)...
    沈念sama閱讀 44,122評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,459評論 2 325
  • 正文 我和宋清朗相戀三年哮兰,在試婚紗的時候發(fā)現(xiàn)自己被綠了毛萌。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,605評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡喝滞,死狀恐怖阁将,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情囤躁,我是刑警寧澤冀痕,帶...
    沈念sama閱讀 34,270評論 4 329
  • 正文 年R本政府宣布,位于F島的核電站狸演,受9級特大地震影響言蛇,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜宵距,卻給世界環(huán)境...
    茶點故事閱讀 39,867評論 3 312
  • 文/蒙蒙 一腊尚、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧满哪,春花似錦婿斥、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至像鸡,卻和暖如春活鹰,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背只估。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評論 1 265
  • 我被黑心中介騙來泰國打工志群, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人蛔钙。 一個月前我還...
    沈念sama閱讀 46,297評論 2 360
  • 正文 我出身青樓锌云,卻偏偏與公主長得像,于是被迫代替她去往敵國和親吁脱。 傳聞我的和親對象是個殘疾皇子桑涎,可洞房花燭夜當晚...
    茶點故事閱讀 43,472評論 2 348

推薦閱讀更多精彩內(nèi)容