Handler源碼分析

Paste_Image.png

Handler

Handler:負(fù)責(zé)發(fā)送和接收消息

1财岔、創(chuàng)建Handler時調(diào)用的它的構(gòu)造函數(shù)Handler(null,false),主要獲取當(dāng)前線程的Looper對象和消息循環(huán)地啰。

    public Handler(Callback callback, boolean async) {
        mLooper = Looper.myLooper();
        mQueue = mLooper.mQueue;
        mCallback = callback;
        mAsynchronous = async;
    }
2、發(fā)送消息sendMessage
  • sendMessage方法遣臼,發(fā)送消息最終調(diào)用的是Handler中的enqueueMessage方法彩届,MessageQueue中的enqueueMessage方法,在消息隊列中通過msg.when將消息放到合適的位置蹦渣。
private boolean enqueueMessage(MessageQueue queue, Message msg,
long uptimeMillis) {
        msg.target = this;
        if (mAsynchronous) {
            msg.setAsynchronous(true);
        }
        return queue.enqueueMessage(msg, uptimeMillis);
}
    ```
* obtainMessage方法哄芜,它是從消息池里面取出一個消息,沒有時才創(chuàng)建消息效率高柬唯。
    
* postDelayed方法认臊,此方法需要傳一個Runnable對象,最終賦值給Message的callback屬性权逗。

private static Message getPostMessage(Runnable r) {
Message m = Message.obtain();
m.callback = r;
return m;
}

######3美尸、分發(fā)消息dispatchMessage

public void dispatchMessage(Message msg) {
//如果callback不為空,直接調(diào)用
if (msg.callback != null) {
message.callback.run();
handleCallback(msg);
} else {
//創(chuàng)建Handler時斟薇,傳遞的Callback接口,默認(rèn)為null恕酸。
if (mCallback != null) {
if (mCallback.handleMesscage(msg)) {
return;
}
}
handleMessage(msg);//回調(diào)子類方法堪滨,在Handler類里面只是聲明。
}
}

###Looper:
* 1蕊温、ThreadLocal類
    它的作用是為每一個線程保存一份變量袱箱,內(nèi)部其實用一個數(shù)組來表示遏乔,對索引進(jìn)行散列保證內(nèi)部均勻。
    >ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
    
* 2发笔、prepare方法準(zhǔn)備操作
    準(zhǔn)備Looper類盟萨,在Looper構(gòu)造函數(shù)里面創(chuàng)建消息隊列和獲取當(dāng)前線程。將線程和Looper進(jìn)行關(guān)聯(lián)起來了讨。
private static void prepare(boolean quitAllowed) {
    if (sThreadLocal.get() != null) {
        throw new RuntimeException("Only one Looper may be created 
                   per thread");
    }
    sThreadLocal.set(new Looper(quitAllowed));
}
private Looper(boolean quitAllowed) {
    mQueue = new MessageQueue(quitAllowed);
    mThread = Thread.currentThread();
}
* 3捻激、loop方法
    使消息進(jìn)行分發(fā)
public static void loop() {
    final Looper me = myLooper();
    if (me == null) {
        throw new RuntimeException("No Looper; Looper.prepare() 
               wasn't called on this thread.");
    }
    final MessageQueue queue = me.mQueue;
    for (;;) {
        Message msg = queue.next(); // might block
        if (msg == null) {
            return;// No message indicates that the message 
        }
        msg.target.dispatchMessage(msg);//消息分發(fā)
        msg.recycle();//回收消息
    }
}
    
###Message:
* 屬性target
發(fā)送消息時將消息的target屬性設(shè)置為this(就是Handler),在通過msg.target.dispatchMessage方法可以找到發(fā)送消息的Handler前计。
    
###MessageQueue:
*  1胞谭、獲取消息
    queue.next(),通過msg.when進(jìn)行計算出合適的Message.
    
    
###ActivityThread
    
Android程序入口函數(shù)是ActivityThread的main函數(shù),在這里先調(diào)用Looper.prepareMainLooper方法男杈,創(chuàng)建ActivityThread.

final ApplicationThread mAppThread = new ApplicationThread();
private void attach(boolean system) {
if (!system) {
RuntimeInit.setApplicationObject(mAppThread.asBinder());
final IActivityManager mgr = ActivityManagerNative.getDefault();
mgr.attachApplication(mAppThread);
} else {
android.ddm.DdmHandleAppName.setAppName("system_process",
UserHandle.myUserId());
mInstrumentation = new Instrumentation();
ContextImpl context = ContextImpl.createAppContext(this,
getSystemContext().mPackageInfo);
mInitialApplication = context.mPackageInfo.makeApplication(true, null);
mInitialApplication.onCreate();
}
}


public static void main(String[] args) {
//創(chuàng)建
Looper.prepareMainLooper();
ActivityThread thread = new ActivityThread();
thread.attach(false);
//
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
Looper.loop();
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末丈屹,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子伶棒,更是在濱河造成了極大的恐慌旺垒,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,273評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件肤无,死亡現(xiàn)場離奇詭異先蒋,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)舅锄,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,349評論 3 398
  • 文/潘曉璐 我一進(jìn)店門鞭达,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人皇忿,你說我怎么就攤上這事畴蹭。” “怎么了鳍烁?”我有些...
    開封第一講書人閱讀 167,709評論 0 360
  • 文/不壞的土叔 我叫張陵叨襟,是天一觀的道長。 經(jīng)常有香客問我幔荒,道長糊闽,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,520評論 1 296
  • 正文 為了忘掉前任爹梁,我火速辦了婚禮右犹,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘姚垃。我一直安慰自己念链,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,515評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著掂墓,像睡著了一般谦纱。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上君编,一...
    開封第一講書人閱讀 52,158評論 1 308
  • 那天跨嘉,我揣著相機(jī)與錄音,去河邊找鬼吃嘿。 笑死祠乃,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的唠椭。 我是一名探鬼主播跳纳,決...
    沈念sama閱讀 40,755評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼贪嫂!你這毒婦竟也來了寺庄?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,660評論 0 276
  • 序言:老撾萬榮一對情侶失蹤力崇,失蹤者是張志新(化名)和其女友劉穎斗塘,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體亮靴,經(jīng)...
    沈念sama閱讀 46,203評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡馍盟,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,287評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了茧吊。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片贞岭。...
    茶點(diǎn)故事閱讀 40,427評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖搓侄,靈堂內(nèi)的尸體忽然破棺而出瞄桨,到底是詐尸還是另有隱情,我是刑警寧澤讶踪,帶...
    沈念sama閱讀 36,122評論 5 349
  • 正文 年R本政府宣布芯侥,位于F島的核電站,受9級特大地震影響乳讥,放射性物質(zhì)發(fā)生泄漏柱查。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,801評論 3 333
  • 文/蒙蒙 一云石、第九天 我趴在偏房一處隱蔽的房頂上張望唉工。 院中可真熱鬧,春花似錦汹忠、人聲如沸酵紫。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,272評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽奖地。三九已至,卻和暖如春赋焕,著一層夾襖步出監(jiān)牢的瞬間参歹,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,393評論 1 272
  • 我被黑心中介騙來泰國打工隆判, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留犬庇,地道東北人。 一個月前我還...
    沈念sama閱讀 48,808評論 3 376
  • 正文 我出身青樓侨嘀,卻偏偏與公主長得像臭挽,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子咬腕,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,440評論 2 359

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