W3Cschool
恭喜您成為首批注冊(cè)用戶
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
編寫(xiě):jdneo - 原文:http://developer.android.com/training/cloudsync/gcm.html
谷歌云消息(GCM)是一個(gè)用來(lái)給Android設(shè)備發(fā)送消息的免費(fèi)服務(wù),它可以極大地提升用戶體驗(yàn)。利用GCM消息,你的應(yīng)用可以一直保持更新的狀態(tài),同時(shí)不會(huì)使你的設(shè)備在服務(wù)器端沒(méi)有可用更新時(shí),喚醒無(wú)線電并對(duì)服務(wù)器發(fā)起輪詢(這會(huì)消耗大量的電量)。同時(shí),GCM可以讓你最多一次性將一條消息發(fā)送給1,000個(gè)人,使得你可以在恰當(dāng)?shù)貢r(shí)機(jī)很輕松地聯(lián)系大量的用戶,同時(shí)大量地減輕你的服務(wù)器負(fù)擔(dān)。
這節(jié)課將包含一些把GCM集成到應(yīng)用中的最佳實(shí)踐方法,前提是假定你已經(jīng)對(duì)該服務(wù)的基本實(shí)現(xiàn)有了一個(gè)了解。如果不是這樣的話,你可以先閱讀一下:GCM demo app tutorial。
一個(gè)GCM最有用的特性之一是單條消息最多可以發(fā)送給1,000個(gè)接收者。這個(gè)功能可以更加簡(jiǎn)單地將重要消息發(fā)送給你的所有用戶群體。例如,比方說(shuō)你有一條消息需要發(fā)送給1,000,000個(gè)人,而你的服務(wù)器每秒能發(fā)送500條消息。如果你的每條消息只能發(fā)送給一個(gè)接收者,那么整個(gè)消息發(fā)送過(guò)程將會(huì)耗時(shí)1,000,000/500=2,000秒,大約半小時(shí)。然而,如果一條消息可以一次性地發(fā)送給1,000個(gè)人的話,那么耗時(shí)將會(huì)是(1,000,000/1,000)/500=2秒。這不僅僅體現(xiàn)出了GCM的實(shí)用性,同時(shí)對(duì)于一些實(shí)時(shí)消息而言,其重要性也是不言而喻的。就比如災(zāi)難預(yù)警或者體育比分播報(bào),如果延遲了30分鐘,消息的價(jià)值就大打折扣了。
想要利用這一功能非常簡(jiǎn)單。如果你使用的是Java語(yǔ)言版本的GCM helper library,只需要向send
或者sendNoRetry
方法提供一個(gè)注冊(cè)ID的List就行了(不要只給單個(gè)的注冊(cè)ID):
// This method name is completely fabricated, but you get the idea.
List regIds = whoShouldISendThisTo(message);
// If you want the SDK to automatically retry a certain number of times, use the
// standard send method.
MulticastResult result = sender.send(message, regIds, 5);
// Otherwise, use sendNoRetry.
MulticastResult result = sender.sendNoRetry(message, regIds);
如果想用除了Java之外的語(yǔ)言實(shí)現(xiàn)GCM支持,可以構(gòu)建一個(gè)帶有下列頭部信息的HTTP POST請(qǐng)求:
Authorization: key=YOUR_API_KEY
Content-type: application/json
之后將你想要使用的參數(shù)編碼成一個(gè)JSON對(duì)象,列出所有在registration_ids
這個(gè)Key下的注冊(cè)ID。下面的代碼片段是一個(gè)例子。除了registration_ids
之外的所有參數(shù)都是可選的,在data
內(nèi)的項(xiàng)目代表了用戶定義的載荷數(shù)據(jù),而非GCM定義的參數(shù)。這個(gè)HTTP POST消息將會(huì)發(fā)送到:https://android.googleapis.com/gcm/send
:
{ "collapse_key": "score_update",
"time_to_live": 108,
"delay_while_idle": true,
"data": {
"score": "4 x 8",
"time": "15:16.2342"
},
"registration_ids":["4", "8", "15", "16", "23", "42"]
}
關(guān)于更多GCM多播消息的格式,可以閱讀:Sending Messages。
GCM經(jīng)常被用作為一個(gè)觸發(fā)器,它告訴移動(dòng)應(yīng)用向服務(wù)器發(fā)起鏈接并更新數(shù)據(jù)。在GCM中,可以(也推薦)在新消息要替代舊消息時(shí),使用可折疊的消息(Collapsible Messages)。我們用體育比賽作為例子,如果你向所有用戶發(fā)送了一條包含了當(dāng)前比賽比分的消息,15分鐘之后,又發(fā)送了一條消息更新比分,那么第一條消息就沒(méi)有意義了。對(duì)于那些還沒(méi)有收到第一條消息的用戶,就沒(méi)有必要將這兩條消息全部接收下來(lái),何況如果要接收兩條消息,那么設(shè)備不得不進(jìn)行兩次響應(yīng)(比如對(duì)用戶發(fā)出通知或警告),但實(shí)際上兩條消息中只有一條是重要的。
當(dāng)你定義了一個(gè)折疊Key,此時(shí)如果有多個(gè)消息在GCM服務(wù)器中,以隊(duì)列的形式等待發(fā)送給同一個(gè)用戶,那么只有最后的那一條消息會(huì)被發(fā)出。對(duì)于之前所說(shuō)的體育比分的例子,這樣做能讓設(shè)備免于處理不必要的任務(wù),也不會(huì)讓設(shè)備對(duì)用戶造成太多打擾。對(duì)于其他的一些場(chǎng)景比如與服務(wù)器同步數(shù)據(jù)(檢查郵件接收),這樣做的話可以減少設(shè)備需要執(zhí)行同步的次數(shù)。例如,如果有10封郵件在服務(wù)器中等待被接收,并且有10條GCM消息發(fā)送到設(shè)備提醒它有新的郵件,那么實(shí)際上只需要一個(gè)GCM就夠了,因?yàn)樵O(shè)備可以一次性把10封郵件都同步了。
為了使用這一特性,只需要在你要發(fā)出的消息中添加一個(gè)消息折疊Key。如果你在使用GCM helper library,那么就使用Message類的collapseKey(String key)
方法。
Message message = new Message.Builder(regId)
.collapseKey("game4_scores") // The key for game 4.
.ttl(600) // Time in seconds to keep message queued if device offline.
.delayWhileIdle(true) // Wait for device to become active before sending.
.addPayload("key1", "value1")
.addPayload("key2", "value2")
.build();
如果你沒(méi)有使用GCM helper library,那么就直接在你要構(gòu)建的POST頭部中添加一個(gè)字段。將collapse_key
作為字段名,并將Key的名稱作為該字段的值。
通常, GCM消息被用作為一個(gè)觸發(fā)器,或者用來(lái)告訴設(shè)備,在服務(wù)器或者別的地方有一些待更新的數(shù)據(jù)。然而,一條GCM消息的大小最大可以有4kb,因此,有時(shí)候可以在GCM消息中放置一些簡(jiǎn)單的數(shù)據(jù),這樣的話設(shè)備就不需要再去和服務(wù)器發(fā)起連接了。在下列條件都滿足的情況下,我們可以將數(shù)據(jù)放置在GCM消息中:
例如,短消息或者回合制網(wǎng)游中玩家的移動(dòng)數(shù)據(jù)等都是將數(shù)據(jù)直接嵌入在GCM消息中的例子。而電子郵件就是反面例子了,因?yàn)殡娮余]件的數(shù)據(jù)量一般都大于4kb,而且用戶一般不需要對(duì)每一封新郵件都收到一個(gè)GCM提醒的消息。
同時(shí)在發(fā)送多播消息時(shí),也可以考慮這一方法,這樣的話就不會(huì)導(dǎo)致大量用戶在接收到GCM的更新提醒后,同時(shí)向你的服務(wù)器發(fā)起連接。
這一策略不適用于發(fā)送大量的數(shù)據(jù),有這么一些原因:
如果恰當(dāng)?shù)厥褂?,直接將?shù)據(jù)嵌入到GCM消息中,可以加速你的應(yīng)用的“感知速度”,因?yàn)檫@樣一來(lái)它就不必再去服務(wù)器獲取數(shù)據(jù)了。
你的應(yīng)用不應(yīng)該僅僅對(duì)收到的GCM消息進(jìn)行響應(yīng)就夠了,還應(yīng)該響應(yīng)地更智能一些。至于如何響應(yīng)需要結(jié)合具體情況而定。
不要太過(guò)激進(jìn)
當(dāng)提醒用戶去更新數(shù)據(jù)時(shí),很容易不小心從“有用的消息”變成“干擾消息”。如果你的應(yīng)用使用狀態(tài)欄通知,那么應(yīng)該更新現(xiàn)有的通知,而不是創(chuàng)建第二個(gè)。如果你通過(guò)鈴聲或者震動(dòng)的方式提醒用戶,一定要設(shè)置一個(gè)計(jì)時(shí)器。不要讓?xiě)?yīng)用每分鐘的提醒頻率超過(guò)1次,不然的話用戶很可能會(huì)不堪其擾而卸載你的應(yīng)用,關(guān)機(jī),甚至把手機(jī)扔到河里。
用聰明的辦法同步數(shù)據(jù),別用笨辦法
當(dāng)使用GCM告知設(shè)備有數(shù)據(jù)需要從服務(wù)器下載時(shí),記住你有4kb大小的數(shù)據(jù)可以和消息一起發(fā)出,這可以幫助你的應(yīng)用做出更智能的響應(yīng)。例如,如果你有一個(gè)支持訂閱的閱讀應(yīng)用,而你的用戶訂閱了100個(gè)源,那么這就可以幫助你的應(yīng)用更智能地決定應(yīng)該去服務(wù)器下載什么數(shù)據(jù)。下面的例子說(shuō)明了在GCM載荷中可以發(fā)送什么樣的數(shù)據(jù),以及設(shè)備可以做出什么樣的反應(yīng):
refresh
- 你的應(yīng)用被告知向每一個(gè)源請(qǐng)求數(shù)據(jù)。此時(shí)你的應(yīng)用可以向100個(gè)不同的服務(wù)器發(fā)起獲取訂閱內(nèi)容的請(qǐng)求,或者如果你在服務(wù)器上有一個(gè)聚合服務(wù),那么可以只發(fā)送一個(gè)請(qǐng)求,將100個(gè)源的數(shù)據(jù)進(jìn)行打包并讓設(shè)備獲取,這樣一次性就完成更新。refresh, freshID
- 一種更好的解決方案,你的應(yīng)用可以有針對(duì)性的完成更新。refresh, freshID, timestamp
- 三種方案中最好的,如果正好用戶在收到GCM消息之前手動(dòng)做了更新,那么應(yīng)用可以利用時(shí)間戳和當(dāng)前的更新時(shí)間進(jìn)行對(duì)比,并決定是否有必要執(zhí)行下一步的行動(dòng)。Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: