讨論逾時的細節之前,我們先講講對應用開發有幫助的,為什麼前台隊列比背景隊列要快?
應用開發的同學在給系統團隊提意見的時候講,說以前我們都是靠通過将廣播消息設成前台廣播的方式來做workaround來解決一些廣播的性能問題的,你們系統為什麼不能将背景廣播做得跟前台廣播一樣快呢?這一定是設計上的問題。
其實,這種前台廣播的設計,就是為了加速廣播的性能而設計的。二者在設計思想上就有不同。根據應用層實際的需求,決定使用前台廣播還是背景廣播,本來就是應用設計時候應該考慮的問題。
當然,android的這個設計對應用開發的要求比較高,我看了一些android的教程,也沒有講到這麼細節的東西。系統還是應該更智能一些。
這裡面主要有三點原因:
前台隊列相對比較空閑
前台隊列的逾時時間是10s,而背景是60s. 背景廣播的設計思想就是目前應用優先,盡可能多讓收到廣播的應用有充足的時間把事件做完。而前台廣播的目的是緊急通知,設計上就傾向于目前應用趕快處理完,盡快傳給下一個。
前台隊列不等背景服務,而背景隊列要多等背景服務一定的時間。這還是設計思想上的原因。
比如我們舉個關機廣播的例子,寫應用的同學可以參照這個例子來寫發送前台廣播哈:
比起普通廣播,隻是多加一個intent.addflags(intent.flag_receiver_foreground);就可以了。
不過,紙上得來終覺淺,我們看下實際的代碼中是如何實作的吧。
我們來看ams中的構造函數裡,是如何為前台隊列和背景隊列配置參數的:
我們可以看到有兩點不同:一個是逾時時間不同,另一個是allowdelaybehindservices參數不同,前台是false,就是不等待,而背景是true,要等待。
我們來看看broadcastqueue的構造函數:
timeoutperiod是逾時時間,我們來看看前台和背景的逾時時間是如何定義的:
既然是分析逾時,我們先對broadcastrecord中記錄的幾個時間點有個印象。
其中最繞的是dispatchtime和dispatchclocktime,都是開始分發消息時的時間,它們有什麼不同呢?
其實,它們的差別僅僅是計時方法不同:
其他的時間也都一樣,凡是叫clocktime的都是system.currenttimemillis(),隻叫time的,就是systemclock.uptimemillis().
我們看下它們的實際指派,加深一下印象:
clocktime就這兩個:
非clock的time有三個:
入隊列的邏輯我們在第三講中已經分析過了,我們再複習一下:
這就是剛才我們看到的同時記兩個時間點的那個,在processnextbroadcast中,我們下講會專門分析這個大派發函數:
先看對于并發隊列的派發:
後面還有針對串行隊列的,也是兩個同時要指派喲~
這段邏輯也是在處理廣播消息的主循環processnextbroadcast函數中。
第一處就是剛才看到的位置
另一處是逾時之後,反正也不打算繼續等它了,就把逾時那一刻的時間記錄成收到的時間吧。這段邏輯位于逾時處理的函數broadcasttimeoutlocked中。
這個省事了,隻在一處出現,就是修史書的時候,具體的函數是addbroadcasttohistorylocked.