Android消息機(jī)制及其原理
岱山網(wǎng)站制作公司哪家好,找成都創(chuàng)新互聯(lián)公司!從網(wǎng)頁設(shè)計(jì)、網(wǎng)站建設(shè)、微信開發(fā)、APP開發(fā)、自適應(yīng)網(wǎng)站建設(shè)等網(wǎng)站項(xiàng)目制作,到程序開發(fā),運(yùn)營維護(hù)。成都創(chuàng)新互聯(lián)公司于2013年成立到現(xiàn)在10年的時(shí)間,我們擁有了豐富的建站經(jīng)驗(yàn)和運(yùn)維經(jīng)驗(yàn),來保證我們的工作的順利進(jìn)行。專注于網(wǎng)站建設(shè)就選成都創(chuàng)新互聯(lián)公司。
Handle的原理
andriod提供了Handler和Looper來滿足線程間的通信。Handler先進(jìn)先出原則。Looper類用來管理特定線程內(nèi)對象之間的消息交換(MessageExchange)。
MessageQueue
MessageQueue是持有Message(在Looper中派發(fā))的一個(gè)鏈表,Message并不是直接添加到MessageQueue中的,而是通過與Looper相關(guān)聯(lián)的Handler來進(jìn)行的。
用來存放線程放入的消息,讀取會自動(dòng)刪除消息,單鏈表維護(hù),在插入和刪除上有優(yōu)勢。在其next()中會無限循環(huán),不斷判斷是否有消息,有就返回這條消息并移除。
Looper
一個(gè)線程可以產(chǎn)生一個(gè)Looper對象,由它來管理此線程里的MessageQueue
Looper創(chuàng)建的時(shí)候會創(chuàng)建一個(gè)MessageQueue,調(diào)用loop()方法的時(shí)候消息循環(huán)開始,loop()也是一個(gè)死循環(huán),會不斷調(diào)用messageQueue的next(),當(dāng)有消息就處理,否則阻塞在messageQueue的next()中。當(dāng)Looper的quit()被調(diào)用的時(shí)候會調(diào)用messageQueue的quit(),此時(shí)next()會返回null,然后loop()方法也跟著退出。
MessageQueue和Looper是一對一關(guān)系,Handler和Looper是多對一
Handler
在主線程構(gòu)造一個(gè)Handler,與Looper溝通,以便push新消息到MessageQueue里;
接收Looper從MessageQueue取出Handler所送來的消息。然后在其他線程調(diào)用sendMessage(),此時(shí)主線程的MessageQueue中會插入一條message,然后被Looper使用.
Thread
UIthread 通常就是main thread,而Android啟動(dòng)程序時(shí)會替它建立一個(gè)MessageQueue,系統(tǒng)的主線程在ActivityThread的main()為入口開啟主線程,其中定義了一系列消息類型,包含四大組件的啟動(dòng)停止。
消息隊(duì)列分發(fā)算法源碼
每個(gè)message之間拉手,知道自己前面和后面的message
message通過時(shí)間戳來排序,小的在前
配合handle取出message,message時(shí)間到,就去除隊(duì)列首個(gè)message,取出之后置為null,第二個(gè)message就排在第一,類推
//消息的存放
boolean enqueueMessage(Message msg, long when) {
synchronized (this) {
? ? msg.when = when;
? ? Message p = mMessages;? //注解1
? ? if (p == null || when == 0 || when p.when){
? ? ? ? msg.next = p;
? ? ? ? mMessages = msg;? ? //注解2
? ? } else {
? ? ? ? Message prev;
? ? ? ? for (;;) {? ? ? ? ? //注解3
? ? ? ? ? ? prev = p;
? ? ? ? ? ? p = p.next;
? ? ? ? ? ? if (p == null || when p.when) {
? ? ? ? ? ? ? ? break;
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? msg.next = p;
? ? ? ? prev.next = msg;
? ? }
}
return true;
}
參考文章:
1. 主流的第三方推送平臺分類
手機(jī)廠商類:小米推送、華為推送。
第三方平臺類:友盟推送、極光推送、云巴(基于MQTT)
BAT大廠的平臺推送:阿里云移動(dòng)推送、騰訊信鴿推送、百度云推送
2. 對比其他推送方式的特點(diǎn)
其他推送方式還有:C2DM、輪詢、SMS、MQTT協(xié)議、XMPP協(xié)議等等,相對于這些推送方式,第三方推送方式的特點(diǎn)分別是:
優(yōu)點(diǎn):
成本低
上述的推送大多數(shù)是免費(fèi)的,假如自己實(shí)現(xiàn)則消耗過多資源(開發(fā)成本和后臺管理、統(tǒng)計(jì)成本)
消息到達(dá)率高
如果一個(gè)手機(jī)里有多個(gè)App使用了同一家推送服務(wù),那么這些App將共用一條消息通道,即使你家的App推送服務(wù)被殺死了,那么只要用戶打開了其他集成該推送服務(wù)的App,你家的推送就能到達(dá)用戶
缺點(diǎn)
安全性低
使用別人的服務(wù)器,所以你懂的。
服務(wù)會被殺死
由于Android系統(tǒng)的機(jī)制,后臺推送 Service 會被各種主動(dòng)的或是被動(dòng)的行為給殺死,而服務(wù)一旦被殺死,意味著就接收不到推送消息。
3. 第三方推送服務(wù)方式的特點(diǎn)
第三方服務(wù)基本都具備免費(fèi)、和到達(dá)率高的特點(diǎn)
那么應(yīng)該如何選擇呢?我們來分別看一下第三方推送各種方式的優(yōu)點(diǎn):
3.1 手機(jī)廠商推送
請記住一個(gè)潛規(guī)則:操作系統(tǒng)是不會殺死屬于自己品牌的推送服務(wù)。
手機(jī)廠商的推送服務(wù)在自家的手機(jī)上屬于系統(tǒng)級別的服務(wù),這意味著系統(tǒng)不會殺死自家的推送服務(wù)
比如說,Android原生系統(tǒng)是不會殺死C2DM消息推送服務(wù),MIUI系統(tǒng)是不會殺死小米的推送服務(wù)。
當(dāng)今市場上的Android手機(jī)系統(tǒng)份額最高是MIUI系統(tǒng),即小米(具體排名請看)
因?yàn)椋好赓M(fèi)、到達(dá)率高且在Android系統(tǒng)市場份額第一的MIUI系統(tǒng)上不被殺死。所以,如果要選擇手機(jī)廠商的推送服務(wù),請選擇小米推送作為第三方平臺實(shí)現(xiàn)推送服務(wù)
下面一些應(yīng)用可以從側(cè)面來證明我的推斷:
騰訊新聞使用的小米推送,沒有使用自己家的信鴿推送
淘寶使用了自家的阿里云推送,同時(shí)還集成了小米推送
百度視頻和愛奇藝使用的是小米推送,沒有用自家的百度推送
官網(wǎng)截圖 - 集成應(yīng)用:
如果希望進(jìn)一步提高推送的效果,其實(shí)可以集成多個(gè)手機(jī)廠商的推送服務(wù)
比如小米渠道用小米推送,華為渠道用華為推送,但這樣的實(shí)現(xiàn)成本會大一些
3.2 第三方平臺類
請記住一個(gè)規(guī)則:推送系統(tǒng)會共享一條推送渠道
這意味著假設(shè)你接入了友盟推送,而恰好今日頭條也接入了友盟。
有一天你的App被殺死了,但這時(shí)用戶啟動(dòng)了今日頭條,那么推送系統(tǒng)也就會通過共享的推送通道順便把你推送消息送達(dá)到手機(jī)上,然后還可能把你的進(jìn)程也喚醒(被“?;睢绷耍?。
所以說,關(guān)于如何選擇第三方平臺類的推送,推送平臺的規(guī)模效應(yīng)就很重要了。
那如何得知他們的規(guī)模和市場份額呢?按個(gè)人經(jīng)驗(yàn),主要看兩點(diǎn):
問內(nèi)部的朋友。
看推送平臺的合作客戶里有哪些大的app - 參考對應(yīng)官網(wǎng)的合作案例
3.3 BAT大廠的推送
BAT大廠其實(shí)并沒有什么優(yōu)勢,同時(shí)謹(jǐn)記:
不要以為用了騰訊信鴿推送,就能占上微信的光保證你的App永遠(yuǎn)內(nèi)部被殺死。
說個(gè)題外話,手機(jī)淘寶除了自家的阿里云的移動(dòng)推送,同時(shí)也使用其它的第三方推送平臺?。ū热缬衙送扑停?/p>
4. 如何選擇第三方平臺推送服務(wù)?
主要從用戶類別+實(shí)現(xiàn)成本+渠道來選擇不同的使用場景
1. 如果用戶群體精準(zhǔn)(使用小米手機(jī)或華為手機(jī)居多),可以考慮只集成對應(yīng)手機(jī)廠商的推送;
注意:單一的手機(jī)廠商也能工作,比如小米推送在非小米手機(jī)上當(dāng)然也能工作,只不過不是系統(tǒng)級別的服務(wù)了,容易被殺死。
如果用戶群體廣泛、希望實(shí)現(xiàn)成本低,可以考慮只使用單一第三方平臺類的推送(極光、友盟blabla,選一個(gè)規(guī)模效應(yīng)最大的)
如果用戶群體廣泛、不在意實(shí)現(xiàn)成本,個(gè)人建議:
對于小米手機(jī),使用小米推送;
對于華為手機(jī),使用華為推送;
對于其他手機(jī),只使用單一第三方平臺類的推送(極光、友盟blabla,選一個(gè)規(guī)模效應(yīng)最大的)
讓不同的推送運(yùn)行在各自擅長的環(huán)境里,最大化實(shí)現(xiàn)推送的到達(dá)率和產(chǎn)品的存活率
大家可以根據(jù)自己的使用場景來進(jìn)行消息推送平臺的選擇。
5. 推送消息類別的選擇
5.1 推送消息的類別
通常第三方推送平臺都支持兩種推送消息類型:通知欄消息和透傳消息。
通知欄消息:該類消息在被送達(dá)用戶的設(shè)備后,直接以系統(tǒng)通知欄的形式展示給用戶
不會繼續(xù)被傳遞到App
透傳消息:該類消息在被送達(dá)用戶的設(shè)備后,還會繼續(xù)傳遞到App
通過回調(diào)App的某個(gè)BroadcastReceiver的形式將消息傳遞到App內(nèi)部。然后由App決定如何處理和顯示這個(gè)消息。
所以透傳消息不一定會以系統(tǒng)通知欄的形式進(jìn)行推送,由程序猿自定義
5.2 消息類別的區(qū)別與特點(diǎn)
二者的區(qū)別在于:透傳消息在整個(gè)消息傳遞過程中比通知欄消息多了一步-傳遞到App
通知欄消息的優(yōu)點(diǎn):送達(dá)率高
因?yàn)橥競飨⒃谡麄€(gè)消息傳遞過程中比通知欄消息多了一步-傳遞到App,因此透傳消息就增加一些被系統(tǒng)限制的概率,給系統(tǒng)殺死的概率就高一些,所以說,通知欄消息比透傳消息應(yīng)該能提供更好的送達(dá)率。
我們來看下小米推送的官方文檔描述:
在一些 Android 系統(tǒng)(如 MIUI)中,受到系統(tǒng)自啟動(dòng)管理設(shè)置的限制,應(yīng)用不能在后臺自啟動(dòng)
在這類系統(tǒng)中,如果在發(fā)送消息的時(shí)候?qū)?yīng)的應(yīng)用沒有被啟動(dòng),透傳類消息將不能順利送達(dá)。
因此,對于對送達(dá)率要求很高的消息,建議盡量采用通知欄提醒的方式推送消息
透傳消息的優(yōu)點(diǎn):對消息操作程度高 自定義程度高
提供了對消息數(shù)據(jù)的更靈活的操縱能力。
App如果僅僅通過通知欄消息,是無法接觸到消息數(shù)據(jù)本身的。
可自定義通知提醒的樣式(包括提示樣式、提示形式如聲音等等)
所以大家可以根據(jù)不同的使用場景來對推送消息類別進(jìn)行選擇了。
可參考vivo手機(jī)的操作方式,進(jìn)入手機(jī)設(shè)置--通知與狀態(tài)欄--應(yīng)用通知管理,找到對應(yīng)軟件,將“允許通知”關(guān)閉,即可取消軟件通知。