Android實現推送方式解決方案

Android實現推送方式解決方案

  本文介紹在Android中實現推送方式的基礎知識及相關解決方案。推送功能在手機開發中應用的場景是越來起來了,不說別的,就我們手機上的新聞客戶端就時不j時的推送過來新的消息,很方便的閱讀最新的新聞信息。這種推送功能是好的一面,但是也會經常看到很多推送過來的垃圾信息,這就讓我們感到厭煩了,關于這個我們就不能多說什么了,畢竟很多商家要做廣告。本文就是來探討下Android中實現推送功能的一些解決方案,也希望能夠起到拋磚引玉的作用。^_^

?

  1.推送方式基礎知識:?

  在移動互聯網時代以前的手機,如果有事情發生需要通知用戶,則會有一個窗口彈出,將告訴用戶正在發生什么事情。可能是未接電話的提示,日歷的提醒,或是一封新的彩信。推送功能最早是被用于Email中,用來提示我們新的信息。由于時代的發展和移動互聯網的熱潮,推送功能更加地普及,已經不再僅僅用在推送郵件了,更多地用在我們的APP中了。

?

  當我們開發需要和服務器交互的應用程序時,基本上都需要獲取服務器端的數據,比如《地震應急通》就需要及時獲取服務器上最新的地震信息。要獲取服務器上不定時更新的信息,一般來說有兩種方法:第一種是客戶端使用Pull(拉)的方式,就是隔一段時間就去服務器上獲取一下信息,看是否有更新的信息出現。第二種就是 服務器使用Push(推送)的方式,當服務器端有新信息了,則把最新的信息Push到客戶端上。這樣,客戶端就能自動的接收到消息。?

?

  雖然Pull和Push兩種方式都能實現獲取服務器端更新信息的功能,但是明顯來說Push方式比Pull方式更優越。因為Pull方式更費客戶端的網絡流量,更主要的是費電量,還需要我們的程序不停地去監測服務端的變化。??

?

  在開發Android和iPhone應用程序時,我們往往需要從服務器不定的向手機客戶端即時推送各種通知消息。我們只需要在Android或IPhone的通知欄處向下一拉,就展開了Notification Panel,可以集中一覽各種各樣通知消息。目前IOS平臺上已經有了比較簡單的和完美的推送通知解決方案,我會在以后詳細介紹IPhone中的解決方案,可是Android平臺上實現起來卻相對比較麻煩。

  最近利用幾天的時間對Android的推送通知服務進行初步的研究,也希望能和大家共同探討一下。

 

  2. 幾種常見的解決方案實現原理:

  1)輪詢(Pull)方式:應用程序應當階段性的與服務器進行連接并查詢是否有新的消息到達,你必須自己實現與服務器之間的通信,例如消息排隊等。而且你還要考慮輪詢的頻率,如果太慢可能導致某些消息的延遲,如果太快,則會大量消耗網絡帶寬和電池。

?

  2)SMS(Push)方式:在Android平臺上,你可以通過攔截SMS消息并且解析消息內容來了解服務器的意圖,并獲取其顯示內容進行處理。這是一個不錯的想法,我就見過采用這個方案的應用程序。這個方案的好處是,可以實現完全的實時操作。但是問題是這個方案的成本相對比較高,我們需要向移動公司繳納相應的費用。我們目前很難找到免費的短消息發送網關來實現這種方案。

?

  3)持久連接(Push)方式:這個方案可以解決由輪詢帶來的性能問題,但是還是會消耗手機的電池。IOS平臺的推送服務之所以工作的很好,是因為每一臺手機僅僅保持一個與服務器之間的連接,事實上C2DM也是這么工作的。不過剛才也講了,這個方案存在著很多的不足之處,就是我們很難在手機上實現一個可靠的服務,目前也無法與IOS平臺的推送功能相比。

?

  Android操作系統允許在低內存情況下殺死系統服務,所以我們的推送通知服務很有可能就被操作系統Kill掉了。 輪詢(Pull)方式和SMS(Push)方式這兩個方案也存在明顯的不足。至于持久連接(Push)方案也有不足,不過我們可以通過良好的設計來彌補,以便于讓該方案可以有效的工作。畢竟,我們要知道GMail,GTalk以及GoogleVoice都可以實現實時更新的。

  

  3.第一種解決方案:C2DM云端推送功能。

  在Android手機平臺上,Google提供了C2DM(Cloudto Device Messaging)服務,起初我就是準備采用這個服務來實現自己手機上的推送功能,并將其帶入自己的項目中。?

?

  Android Cloud to Device Messaging (C2DM)是一個用來幫助開發者從服務器向Android應用程序發送數據的服務。該服務提供了一個簡單的、輕量級的機制,允許服務器可以通知移動應用程序直接與服務器進行通信,以便于從服務器獲取應用程序更新和用戶數據。C2DM服務負責處理諸如消息排隊等事務并向運行于目標設備上的應用程序分發這些消息。關于C2DM具體使用過程,大家可以去查閱相關的資料,在這里先讓我們了解下大致方案情況。

?

  下面是C2DM操作過程示例圖:

   ?

?

  但是經過一番研究發現,這個服務存在很大的問題: ?

  1)C2DM內置于Android的2.2系統上,無法兼容老的1.6到2.1系統;

?

  2)C2DM需要依賴于Google官方提供的C2DM服務器,由于國內的網絡環境,這個服務經常不可用,如果想要很好的使用,我們的App Server必須也在國外,這個恐怕不是每個開發者都能夠實現的;

?

  3)?不像在iPhone中,他們把硬件系統集成在一塊了。所以對于我們開發者來說,如果要在我們的應用程序中使用C2DM的推送功能,因為對于不同的這種硬件廠商平臺,比如摩托羅拉、華為、中興做一個手機,他們可能會把Google的這種服務去掉,尤其像在國內就很多這種,把Google這種原生的服務去掉。買了一些像什么山寨機或者是華為這種國產機,可能Google的服務就沒有了。而像在國外出的那些可能會內置。

?

  有了上述幾個方面的制約,導致我最終放棄了這個方案,不過我想利用另外一篇文章來詳細的介紹C2DM的框架以及客戶端和App Server的相應設置方法,可以作為學習資源讓我們有個參考的資料。 即然C2DM無法滿足我們的要求,那么我們就需要自己來實現Android手機客戶端與App Server之間的通信協議,保證在App Server想向指定的Android設備發送消息時,Android設備能夠及時的收到。

?

  4.?第二種解決方案:MQTT協議實現Android推送功能。

  采用MQTT協議實現Android推送功能也是一種解決方案。MQTT是一個輕量級的消息發布/訂閱協議,它是實現基于手機客戶端的消息推送服務器的理想解決方案。

  wmqtt.jar 是IBM提供的MQTT協議的實現。我們可以從這里(https://github.com/tokudu/AndroidPushNotificationsDemo)下載該項目的實例代碼,并且可以找到一個采用PHP書寫的服務器端實現(https://github.com/tokudu/PhpMQTTClient)。

?

  架構如下圖所示:

  ????

?

  wmqtt.jar?是IBM提供的MQTT協議的實現。我們可以從如下站點下載(http://www-01.ibm.com/support/docview.wss?rs=171&uid=swg24006006)它。我們可以將該jar包加入自己的Android應用程序中。

?

  5.第三種解決方案:RSMB實現推送功能。

  Really Small Message Broker (RSMB)?,他是一個簡單的MQTT代理,同樣由IBM提供,其查看地址是:http://www.alphaworks.ibm.com/tech/rsmb。缺省打開1883端口,應用程序當中,它負責接收來自服務器的消息并將其轉發給指定的移動設備。

?

  SAM是一個針對MQTT寫的PHP庫。我們可以從這個http://pecl.php.net/package/sam/download/0.2.0地址下載它.

  send_mqtt.php是一個通過POST接收消息并且通過SAM將消息發送給RSMB的PHP腳本。?

?

  6.?第四種解決方案:XMPP協議實現Android推送功能。

  這是我希望在項目中采用的方案,因為目前它是開源的,對于其簡單的推送功能它還是能夠實現的。我們可以修改其源代碼來適應我們的應用程序。

  事實上Google官方的C2DM服務器底層也是采用XMPP協議進行的封裝。XMPP(可擴展通訊和表示協議)是基于可擴展標記語言(XML)的協議,它用于即時消息(IM)以及在線探測。這個協議可能最終允許因特網用戶向因特網上的其他任何人發送即時消息。關于XMPP協議我在上篇博文中已經介紹,大家可以參考下文章:http://www.cnblogs.com/hanyonglu/archive/2012/03/04/2378956.html

?

  androidpn是一個基于XMPP協議的java開源Android push notification實現,我會在以后的博文中詳細介紹androidpn。它包含了完整的客戶端和服務器端。經過源代碼研究我發現,該服務器端基本是在另外一個開源工程openfire基礎上修改實現的,不過比較郁悶的是androidpn的文檔是由韓語寫的,所以整個研究過程基本都是讀源碼。

?

  這是androidpn的項目主頁:http://sourceforge.net/projects/androidpn/

?

  androidpn實現意圖如下圖所示:

  

?

  androidpn 客戶端需要用到一個基于java的開源XMPP協議包asmack,這個包同樣也是基于openfire下的另外一個開源項目smack,不過我們不需要自己編譯,可以直接把androidpn客戶端里面的asmack.jar拿來使用。客戶端利用asmack中提供的XMPPConnection類與服 務器建立持久連接,并通過該連接進行用戶注冊和登錄認證,同樣也是通過這條連接,接收服務器發送的通知。

?

  androidpn服務器端也是java語言實現的,基于openfire開源工程,不過它的Web部分采用的是spring框架,這一點與 openfire是不同的。Androidpn服務器包含兩個部分,一個是偵聽在5222端口上的XMPP服務,負責與客戶端的 XMPPConnection類進行通信,作用是用戶注冊和身份認證,并發送推送通知消息。另外一部分是Web服務器,采用一個輕量級的HTTP服務器, 負責接收用戶的Web請求。服務器架構如下:

?

?

?

  最上層包含四個組成部分,分別是SessionManager,Auth Manager,PresenceManager以及Notification Manager。SessionManager負責管理客戶端與服務器之間的會話,Auth Manager負責客戶端用戶認證管理,Presence Manager負責管理客戶端用戶的登錄狀態,NotificationManager負責實現服務器向客戶端推送消息功能。

?

  這個解決方案的最大優勢就是簡單,我們不需要象C2DM那樣依賴操作系統版本,也不會擔心某一天Google服務器不可用。利用XMPP協議我們還可以進一步的對協議進行擴展,實現更為完善的功能。 采用這個方案,我們目前只能發送文字消息,不過對于推送來說一般足夠了,因為我們不能指望通過推送得到所有的數據,一般情況下,利用推送只是告訴手機端服務器發生了某些改變,當客戶端收到通知以后,應該主動到服務器獲取最新的數據,這樣才是推送服務的完整實現。 XMPP協議書相對來說還是比較簡單的,值得我們進一步研究。

?

  但是在經過一段時間的測試,我發現關于androidpn也存在一些不足之處:

  1.?比如時間過長時,就再也收不到推送的信息了。

  2.?性能上也不夠穩定。

?  ?3. 如果將消息從服務器上推送出去,就不再管理了,不管消息是否成功到達客戶端手機上。

?

  等等,總之,androidpn也有很多的缺點。如果我們要使用androidpn,則還需要做大量的工作。

  至于詳細使用過程,我們會在下個博文中再給大家介紹。

?

  7.第五種解決方案:使用第三方平臺。

  第三方平臺有商用的也有免費的,我們可以根據實現情況使用。關于國內的第三方平臺,我感覺目前比較不錯的就是極光推送。關于極光推送目前是免費的,我們可以直接使用。關于詳細情況,大家可以查看它的主頁:http://www.jpush.cn/index.jsp,這里不再詳細描述。

?

  關于MQTT的方案,國內最近出現基于 mqtt 的第三方解決方案 云巴 (http://yunba.io),據了解是原 極光推送 CTO 創辦的,有興趣的朋友可以研究下。

  

  關于國外的第三方平臺我也見過幾個:http://www.push-notification.org/。有興趣的朋友可以查閱相關信息。使用第三方平臺就需要使用別人的服務器,關于這點,你懂的。

?

  8.第六種解決方案:自己搭建一個推送平臺。

  這不是一件輕松的工作,當然可以根據各自的需要采取合適的方案。

?

  好了,以上是關于在Android中實現推送方式的基礎知識及相關解決方案。

?

  最后,希望轉載的朋友能夠尊重作者的勞動成果,加上轉載地址:http://www.cnblogs.com/hanyonglu/archive/2012/03/04/2378971.html?謝謝。

?

轉載于:https://www.cnblogs.com/developer-ios/p/5011809.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/374069.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/374069.shtml
英文地址,請注明出處:http://en.pswp.cn/news/374069.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

NYOJ 2 括號配對問題

括號配對問題 時間限制&#xff1a;3000 ms | 內存限制&#xff1a;65535 KB難度&#xff1a;3描述 現在&#xff0c;有一行括號序列&#xff0c;請你檢查這行括號是否配對。 輸入第一行輸入一個數N&#xff08;0<N<100&#xff09;,表示有N組測試數據。后面的…

您應該對什么進行單元測試? –測試技術3

昨天我在辦公室里&#xff0c;和我的一位同事談論測試&#xff0c;他對編寫單元測試有些不服氣。 他使用的原因之一是有些測試似乎毫無意義&#xff0c;這使我想到了什么是單元測試&#xff0c;什么也不需要打擾。 考慮下面一個簡單的不可變的Name Bean&#xff0c;其中包含一…

java基礎知識系列---垃圾收集

1 為什么要使用垃圾回收機制&#xff1f; “垃圾收集”暗示程序不再需要的對象就是垃圾&#xff0c;可以被丟棄。更精確&#xff0c;更新的說法是“內存回收”。 1.1 新對象的使用 當一個對象不再被程序所引用時&#xff0c;他所使用的堆空間可以被回收&#xff0c;以便于被后續…

經濟

聯合國&#xff0c;美蘇英法中 國家要外匯儲備干什么&#xff1f; 01年加入WTO &#xff0c;美國躲開 WTO 另起爐灶 TPP 諾貝爾經濟學獎得主 克魯格蠻 觸動利益比觸動靈魂還困難 SDR IMF 轉載于:https://www.cnblogs.com/zrui513/p/5014593.html

wxpython的sizer_wxPython BoxSizer布局

Box wx.BoxSizer(wxHORIZONTAL) Box wx.BoxSizer(wxVERTICAL)Add() 方法(從wxSizer繼承)它附加到sizer的下一行/列。Box.Add(control, proportion, flag, border)proportion 參數控制的控件響應于所述容器的尺寸改變其大小。各種flag 參數的組合決定控件在sizer的外觀。下面是…

NYOJ 6 噴水裝置(一)

噴水裝置&#xff08;一&#xff09; 時間限制&#xff1a;3000 ms | 內存限制&#xff1a;65535 KB 難度&#xff1a;3描述 現有一塊草坪&#xff0c;長為20米&#xff0c;寬為2米&#xff0c;要在橫中心線上放置半徑為Ri的噴水裝置&#xff0c;每個噴水裝置的效果都會讓以它為…

如何部署Zabbix服務端

部署環境 RHEL 6.7 Zabbix-server 2.2.14 安裝zabbix官方源 # wget http://repo.zabbix.com/zabbix/2.2/rhel/6/x86_64/zabbix-release-2.2-1.el6.noarch.rpm # rpm -ivh zabbix-release-2.2-1.el6.noarch.rpm 安裝zabbix-server # yum install zabbix zabbix-server-mysql zab…

Google App Engine上的Spring MVC和REST

前段時間&#xff0c;我寫了一篇關于如何使用Spring MVC實現Restful Web API的文章 。 閱讀我以前的文章以了解它。 在那篇文章中&#xff0c;開發了一個簡單的Rest示例。 為了測試該應用程序&#xff0c;將文件復制到Web服務器&#xff08;例如Tomcat &#xff09;中&#xff…

SALT+HASH撒鹽加密

#region 撒鹽加密string salt Guid.NewGuid().ToString();byte[] passwordAndSaltBytes System.Text.Encoding.UTF8.GetBytes(model.Password salt);byte[] hashBytes new System.Security.Cryptography.SHA256Managed().ComputeHash(passwordAndSaltBytes);string hashStr…

python 子串是否在字符串中_python七種方法判斷字符串是否包含子串

1. 使用 in 和 not inin 和 not in 在 Python 中是很常用的關鍵字&#xff0c;我們將它們歸類為 成員運算符。使用這兩個成員運算符&#xff0c;可以很讓我們很直觀清晰的判斷一個對象是否在另一個對象中&#xff0c;示例如下&#xff1a;>>> "llo" in &quo…

NYOJ 8 一種排序

一種排序 時間限制&#xff1a;3000 ms | 內存限制&#xff1a;65535 KB難度&#xff1a;3描述現在有很多長方形&#xff0c;每一個長方形都有一個編號&#xff0c;這個編號可以重復&#xff1b;還知道這個長方形的寬和長&#xff0c;編號、長、寬都是整數&#xff1b;現在要…

css3中的background

對background的兩種運用&#xff1a;一是background中的線性漸變&#xff0c;background: linear-gradient(to bottom,#0e7bef,#0d73da);這個是對背景顏色從上到下的一種線性漸變&#xff08;linear-gradient&#xff09;&#xff0c;兩個顏色參數是從第一個顏色參數漸變到第二…

Oracle JRockit Mission Control 4.1發布

Oracle發布了以前的僅JRockit專用工具Mission Control Suite&#xff08;JRMC&#xff09;的新版本。 4.1版本是次要版本升級&#xff0c;直接遵循4.0.1&#xff08;該版本發布于2010年中期&#xff09;。 但是&#xff0c;即使版本號表明是次要的升級&#xff0c;您仍然可以在…

pe安裝usb3.0驅動_電腦店U盤啟動盤制作工具下載安裝須知

電腦店U盤啟動盤制作工具集成最全面的硬件驅動&#xff0c;精心挑選的系統維護工具&#xff0c;加上獨有人性化的設計&#xff0c;具備較強的兼容性、穩定性和安全性。能夠完美兼容臺式機、品牌機及筆記本等新老機型&#xff0c;且安全無毒&#xff0c;電腦店一鍵U盤啟動盤制作…

Webwork【02】前端OGNL試練

1.OGNL 出現的意義 在mvc中&#xff0c;數據是在各個層次之間進行流轉是一個不爭的事實。而這種流轉&#xff0c;也就會面臨一些困境&#xff0c;這些困境&#xff0c;是由于數據在不同世界中的表現形式不同而造成的&#xff1a; a. 數據在頁面上是一個扁平的&#xff0c;不帶數…

python ATM購物程序

需求&#xff1a; 模擬實現一個ATM 購物商城程序 額度 15000或自定義實現購物商城&#xff0c;買東西加入 購物車&#xff0c;調用信用卡接口結賬可以提現&#xff0c;手續費5%每月22號出賬單&#xff0c;每月10號為還款日&#xff0c;過期未還&#xff0c;按欠款總額 萬分之5…

NYOJ 10 skiing

skiing 時間限制&#xff1a;3000 ms | 內存限制&#xff1a;65535 KB難度&#xff1a;5描述Michael喜歡滑雪百這并不奇怪&#xff0c; 因為滑雪的確很刺激。可是為了獲得速度&#xff0c;滑的區域必須向下傾斜&#xff0c;而且當你滑到坡底&#xff0c;你不得不再次走上坡或…

Spring的REST服務發現性,第5部分

這是有關使用Spring 3.1和Spring Security 3.1和基于Java的配置來建立安全的RESTful Web Service的系列文章的第五篇。 上一篇文章介紹了RESTful服務HATEOAS的可發現性的概念&#xff0c;然后介紹了一些由測試驅動的實際方案。 本文將重點介紹可發現性的實際實現以及使用Spring…

postman使用_postman如何使用集合斷言?

在postman中&#xff0c;大家都使用過斷言&#xff0c;但是我們使用的斷言都是針對每一個接口或者是每一個用例添加的&#xff0c;那么是否有可以同時對多個用例或接口添加斷言呢 &#xff1f; 答案是肯定有的。那么接下來我就帶領大家認識下Postman中的批量斷言&#xff0c;也…

紀念我的leetcode開門之旅

15.12.3在朋友的建議下開始了leetcode之旅&#xff0c;上面的題目先撿簡單的刷吧。。。轉載于:https://www.cnblogs.com/thewaytomakemiracle/p/5016825.html