注:本文翻譯自Google官方的Android Developers Training文檔,譯者技術一般,由于喜愛安卓而產生了翻譯的念頭,純屬個人興趣愛好。
原文鏈接: http://developer.android.com/training/cloudsync/gcm.html
谷歌云消息(GCM)是一個用來給Android設備發送消息的免費服務。GCM消息可以極大地提升用戶體驗。你的應用可以一直保持更新的狀態而不用在喚醒無線電和在沒有更新的使用對服務器發起詢問等事情上消耗電量。同時,GCM可以讓你最多單一的消息可以發送給1000個人,使得你可以在恰當地時候很輕松地聯系大量的用戶,同時大量地減輕你的服務器負擔。
這節課將包含將GCM集成到你的應用中的一些最佳實踐方法,假定你已經對該服務的基本實現有了一個了解。如果不是這樣的話,你可以先閱讀一下: GCM demo app tutorial 。
一). 高效地發送多播消息
一個GCM所支持的最有用的特性是單條消息最多可以發送給1,000個接受者。這個功能可以更加簡單地將重要消息發送給你的所有用戶群體。例如,比方說你有一條消息需要發送給1,000,000個人,而你的服務器每秒能發送500條消息。如果你每次只給一個接受者發送消息,那么將會耗時1,000,000/500=2,000秒,大約半小時。然而,如果一條消息可以一次性地發送給1,000個人的話,那么耗時將會是1,000,000/1,000/5,00=2秒。這不僅僅體現在功能的實用性上,對于具有高時效性的消息而言,比如災難預警或者體育比分播報,如果延遲了30分鐘,消息的價值就大打折扣了。
想要利用這一功能非常簡單。如果你使用Java的 GCM helper library ,只需要像“ send ”或者“ sendNoRetry ”方法提供一個注冊ID的List就行了(不要只給單個的注冊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之外的語言,要實現GCM的支持,可以構建一個帶有下列頭部信息的HTTP POST請求:
-
Authorization: key=YOUR_API_KEY
-
Content-type: application/json
之后將你想要的參數編碼程一個JSON對象,列出所有在“ registration_ids ”這個key下 的注冊ID。下面的代碼片段是一個例子。除了“ registration_ids ”之外的所有參數都是可選的,在“ data ”內的項目代表了用戶定義的載荷數據,而非GCM定義的參數。這個HTTP POST消息將會發送到: 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" ] } ?
關于更多GCM多播的消息格式,可以閱讀: Sending Messages 。
二). 對可替換的消息執行折疊
GCM經常被用作為一個觸發器,告訴移動應用向服務器發起聯系刷新數據。在GCM中,可以(也推薦)在新消息要替代舊消息時,使用可折疊的消息(collapsible messages)。我們用體育比賽作為例子,如果你向所有用戶發送了一條消息包含了比賽的比分,然后再15分鐘后,又發送了一條消息更新新的比分,那么第一條消息就沒有意義了。對于那些還沒有收到第一條消息的用戶,就沒有必要接收兩條消息,并且如果接收了兩條消息,那么設備不得不響應兩次(比如對用戶發出通知或警告),但實際上兩條消息中只有一條是重要的。
當你定義了一個折疊鍵,如果多個消息在GCM服務器中,對于相同的用戶形成了一個隊列,那么只有最后的那一條消息會被發出。對于之前所說的體育比分的例子,這樣做能讓設備免于處理不必要的任務,也不會讓設備對用戶造成太多打擾。對于其他的一些場景比如與服務器同步數據(檢查郵件接收),這樣做的話可以減少設備需要執行的同步次數。例如,如果有10封郵件在服務器中等待被接收,那么實際上只需要發送一個GCM,讓設備一次性把10封郵件都同步了。
為了使用這一特性,只需要在你要發出的消息中添加一個消息折疊key。如果你在使用GCM幫助庫,那么久使用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();
如果你沒有使用幫助庫,那么就直接在你要構建的POST頭部中添加一個變量。 collapse_key作為變量名,你要更新的字段以字符串的形式作為值。
三). 在GCM消息中嵌入數據
通常,?GCM消息作為一個激活器,或者用來告訴設備,有一些待更新的數據需要去服務器或者別的地方去獲取。然而,一個GCM消息的大小最大可以有4kb,有時候可以在GCM消息中放置一些簡單的數據,這樣的話設備就不需要再去和服務器發起連接了。在下列情形都滿足的情況下,我們可以將數據放置在GCM消息中:
- 數據的總大小在4kb以內。
- 每一條消息都很重要,應該保留。
- 這些消息不適用于消息折疊的使用情形。
例如,短消息或者回合制網游中玩家的移動數據等都是將數據直接嵌入在GCM消息中的例子。而電子郵件就是反面例子了。因為電子郵件的數據量一般都大于4kb,且用戶不需要對每個郵件都收到一個GCM提醒的消息。
同時在發送多播消息時,也可以考慮這一方法,這樣的話就不會導致大量用戶在接收到GCM的更新提醒后,同時向你的服務器發起連接。
這一策略不適用于發送大量的數據(你可能會想要中這個方法將數據分割后發送),有這么一些原因:
- 為了防止惡意軟件發送垃圾消息,GCM有發送頻率的限制。
- 無法保證消息按照既定的順序到達。
- 無法保證消息可以在你發送后立即到達。假設設備每一秒都接收一條消息,最大為1K,即8kbps,或者說是1990年代的家庭撥號上網的速度。那么如此大量的消息,一定會讓你的應用在Google Play上的評分非常尷尬。
如果恰當地使用,直接將數據嵌入到GCM消息中,可以加速你的應用的“感知速度”,因為它不必再去服務器獲取數據了。
四). 智能地響應GCM消息
你的應用不應該僅僅對收到的GCM消息進行響應就夠了,還應該響應地更智能一些。至于要如何響應需要結合具體情況而定。
不要太過激進
當提醒用戶區更新數據時,很容易不小心從“ 有用的消息 ”變成“ 干擾消息 ”。如果你的應用使用狀態欄通知,那么應該 更新現有的通知 ,而不是創建第二個。如果你通過鈴聲或者震動的方式提醒用戶,一定要設置一個計時器。不要讓應用的提醒時間超過1分鐘,不然的話用戶很可能為不堪其擾二卸載你的應用,關機,或者把手機扔到河里:)
用聰明的辦法同步數據,別用笨辦法
當使用GCM告知設備有數據需要從服務器下載時,記住你有4kb的數據大小和消息一起發出,這可以幫助你的應用做出更智能地響應。例如,如果你有一個源閱讀應用,而你的用戶訂閱了100個源,那么這就可以幫助你的應用更智能地決定應該去服務器下載什么數據。下面的例子說明了在GCM載荷中可以發送那些數據,以及設備可以做出什么樣的反應:
- refresh - 你的應用被告知向每一個源請求數據。此時你的應用可以向100個不同的服務器發起獲取源的請求,或者如果你在你的服務器上有一個聚合服務,那么可以只發送一個請求,將100個源的數據進行打包并獲取,這樣一次性完成更新。
- refresh, freshID - 一種更好的解決方案,你的應用可以有針對性的完成更新。
- refresh, freshID, timestamp - 一種更好的解決方案,如果正好用戶在GCM消息收到之前手動做了更新,那么應用可以利用時間戳和當前的更新時間進行對比,并決定是否要執行下一步的行動。
【Android Developers Training】 89. 最大化的使用谷歌云消息(Google Cloud Messaging)
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
