1. 程式人生 > >Android訊息推送叨逼叨

Android訊息推送叨逼叨

         最近在搞即時訊息推送。瞭解了推送服務實現的基本原理。通過長連線去實現及時的推送,或者通過輪詢的方式去實現偽及時的推送。當然,通常我們選擇前者。如果實現長連線就要用到socket,所以簡單瞭解了下socket程式設計。又因為伺服器端需要考慮大併發、效能方面的問題。直接使用socket在效能上無法保證,需要使用java提供的非阻塞式的高伸縮性的網路I/O:nio;因為nio程式設計比較複雜,開發過程中都是使用現有的框架:MINA或者Netty。我們開發的推送服務是基於AndroidPN這個開源專案實現的。AndroidPn伺服器端使用的就是MINA框架。然後又去了解了一下MINA伺服器。有了上面的一些理論基礎後,就去開開心心的看AndroidPn的原始碼,修改裡面的BUG,去實現自己需要的功能。這裡並不去過多的介紹AndroidPn。從上週的工作內容講起。

          推送服務基本實現後,開始著重考慮客戶端一直存在的問題。我們都知道要想實現即時的通訊。就必須在客戶端和伺服器端之間建立一個長連線。而在Android客戶端要想維持這個長連線,就要在後臺開個單獨的程序去維護這個長連線。我的噩夢開始了,使用者可以選擇隨時清空系統記憶體。或者動不動就按下一鍵加速什麼的。那麼我們執行在後臺的為了保證及時通訊的長連線的服務就會隨時被殺掉。大家最常用的辦法就是在JNI裡面fork出子程序,然後監視 service程序狀態,被系統殺死了就重啟它。這個辦法在5.0之後已經不起作用了。為什麼5.0上面就不行了呢,咱們看一下activitymanagerservice,LBE的清理記憶體應該呼叫的killBackgroundProcesses,看看他們有什麼區別

   5.0的程式碼:

 Process.killProcessQuiet(app.pid);
 Process.killProcessGroup(app.info.uid, app.pid);
   4.3的程式碼:

   Process.killProcessQuiet(app.pid);

 5.0中增加了Group的概念,對同一應用的程序進行統一管理了。當然我們還可以通過一些其他的方式來保證我們的服務長期執行,比如監聽系統廣播,使用者一開機,或者使用者手機網路發生變化的時候就去啟動我們的服務等等這些“見不得人的”辦法。作為有良知的程式設計師,我們深知這種流氓做法並不可取,但是在需求面前,程式設計師是沒有自己的。不過這種方式效果不盡人意。監聽的各種廣播在某些ROM比如小米的MIUI,預設是關閉的,需要使用者手動開啟,哎,至少到目前為止,我還沒開發出來能讓使用者欣喜若狂的選擇開機啟動、監聽各種各樣的系統廣播的APP ╮(╯▽╰)╭。然後我就想是不是其他開發人員是不是也跟我有同樣的煩惱,他們是不是也在想盡辦法來讓自己的服務能夠儘可能長的在後臺執行。去網上查了下,這方面的內容很多,提供了各種各樣的解決辦法,目的也多半都是為了保證伺服器可以即時的與客戶端進行通訊。為什麼Android的手機這麼卡,為什麼電池會用的那麼快。其中一個原因,每個程式都後在後臺建立一個長連線,並不斷髮送心跳包去保證自己的APP可以收到訊息。如果你的APP很不巧的集成了不同廠商提供的推送服務。或者連結的自己搭建的推送伺服器。那麼你要及時清理你的後臺應用了,不然會有N多個長連線去不斷的傳送心跳包,去強姦你的記憶體、電量、流量,並且沒人為此負責。這也是Android手機效能如此強悍,電池容量如此之大,仍然不敵iPhone的原因之一。

     那麼蘋果的是怎麼去管理推送的呢。Iphone在系統層建立了一個長連線,去連線你的手機裝置和蘋果自家的推送伺服器APNS(Apple Push NotificaitonService);這個長連線是全域性的、獨立於每一個APP之外的。應用提供商把訊息推送給APNS,APNS藉助於系統級的長連線把訊息推送給客戶端。這樣應用本身就不用常駐的後臺程序去管理長連線(當然蘋果也不允許你這麼做)。當蘋果把大量的資源開銷放在了雲端,而非裝置上,手機系統開銷小了,手機更流暢,電量更耐用。

                      

這是APNS的邏輯所在:IOS系統自己做個長連線。所有應用都必須申請、並且允許才能通過雲端伺服器把訊息通過系統級的長連線傳送過來。

這樣帶來的好處是實實在在的:

                ①  安全:只有登陸過的開發者可以通過蘋果的伺服器推送訊息。

                ②  快速、穩定、可靠:蘋果自己掌控長連線和推送伺服器。

                ③  更省電、省記憶體、省流量

                ④  整個系統的體驗更加一致和簡單。不用考慮殺記憶體這種腦殘事,更不會出現殺記憶體收不到推送的蛋疼                           事。

         為什麼Android不自己搞個類似的功能呢。其實Android也有,叫GCM(Google Clond Message)。而且在國外很多應用也是用這個服務進行推送的。比如WhatsApp、推特等。但是在國內使用的GCM去推自己訊息應該沒幾家吧。原因:

              ① GCM作為谷歌的服務經常被牆;

              ② GCM設定的心跳間隔過長,並不適合國內比較坑的網路環境;

              ③ 國內的第三方ROM會把GCM閹割掉;

              ④ 需要繫結Google賬號(此要求在Android4.0.4版本後解除)……

總之GCM在國內水土不服。所以Google把GCM做成了可選項。而不是像蘋果那樣去讓第三方開發商強制接入APNS。這個除了因為Android更開放之外,更多的可能是Google的無奈。他們的決策層肯定也清楚的知道讓程式設計師們自己去實現一個服務維護各自應用與推送伺服器的長連線會把系統資源搞得亂七八糟的,是各種坑爹的。但是市場環境如此。Google的服務何時能夠王者歸來,何時不再放縱手機廠商任意閹割google服務,還是個未知數。(借用網友的一張圖)

                     

        基於以上事實,我們會發現國內各種推送平臺應運而生。百度推送、極光推送、友盟推送、信鴿推送、個推…..這些都是GCM的替代品。如果這些推送能夠互相殘殺,並最終實現一家獨大,原理上我們就可以實現APNS那樣的效果。因為上面這些推送有些是單通道的。意思就是如果你的手機上的所有應用都使用的百度的推送,實際上這些應用使用的是同一條通道,同一個長連線。跟APNS的原理一致。但事實上是推送市場列國混戰,每個廠商身後都有個網際網路巨頭,每個廠商都用免費去吸引更多的APP接入到自家平臺。目的很簡單,當用戶量足夠大的時候就變成了一種隱形的標準。大家都在我這玩。你不來我這,就沒法和大家一起玩耍。所以每個廠家都去搶佔APP的流量入口。以期在將來的網際網路大戰中佔得先機。所有在想Android端去體驗iPhone那樣穩定、快速、可靠的推送服務,還遙遙無期。使用第三方推送有些人擔心一件事情:他們免費給我們用是為了獲取我們的資料,去做資料分析,去搞見不到人的事。我只能說,就你那app的使用者量,就你推送的那點資料,你自己都不想做資料分析,也好意思!雖然我不能排除雲服務廠商會那樣去做。但是因為這個原因去否定雲服務,只能說有些頑固不化了。

       除了使用第三方的推送服務,也可行自己搞一個出來,正如我們公司現在做的那樣,為什麼自己要開發一套推送服務呢。主要有幾個方面的考慮:

                    ①  我們的資料的的確確不能讓外部知道,是絕對的保密的。

                    ②  出於工作環境的考慮,我們的客戶端和伺服器端都無法與外部連結,是執行在區域網內的。

                    ③  我們不想受制於人,把權力掌握在自己手裡,哪怕能力原因我們受制於自己。

                    ④  出於工作成果的考慮,相比於花幾個小時整合第三方的推送服務,自己搭建一套推送服務,要顯                                  得牛逼的多O(∩_∩)O~。

           寫在最後:Android的推送服務還是比較坑的,不管是整合第三方還是自己搭建一套推送伺服器,都無法實現像APNS那樣優雅的推送。使用第三方的推送服務,尤其是使用了市場佔有率比較高的推送服務,那麼我們推送的到達率相對而言要高些。使用自己搭建的伺服器或者使用了比較小眾的第三方推送平臺,我們在後臺維護的那個長連線相比於百度或者騰訊的長連線更容易被殺掉。我們可能同時有幾個應用程式都集成了百度的推送,那麼集成了百度推送的APP在前臺執行的概率就會大一些,維持著長連線的程序更容易存活。我們的APP可以與推送伺服器保持更好的連線,正如我們前面提到的,他是單通道的。而自己開發維護的長連線可能並沒那麼幸運。如果應用程式沒有開啟,基本是接收不到訊息的,除非我們的APP足夠流氓,怎麼都殺不死。永遠在後臺執行。搭建一套推送伺服器的開發成本,和維護成本對於小企業是很難接受的。對於開發人員:如果有機會自己搭建一套推送伺服器,還是很難得的,畢竟很少有企業願意花大量時間讓你研究這個東西。相比於整合第三方的推送服務,自己開發,能讓我們對推送的原理、機制有比較深刻的認識,甚至對Android的執行機制有一些新的認識。另外,在一定程度上,也有利於我們去比較和衡量不同推送服務提供商的產品的優劣,做出更合理的選擇。

           (第一次發文章,好激動,可能有理解不對的地方,求吐槽)

相關推薦

Android訊息

         最近在搞即時訊息推送。瞭解了推送服務實現的基本原理。通過長連線去實現及時的推送,或者通過輪詢的方式去實現偽及時的推送。當然,通常我們選擇前者。如果實現長連線就要用到socket,所以簡單瞭解了下socket程式設計。又因為伺服器端需要考慮大併發、效能方面的

基於Netty實現的Android 訊息(即時通訊)的解決方案

根據Netty框架實現訊息推送(即時聊天)功能. Netty框架,TCP長連線,心跳,阻塞訊息佇列,執行緒池處理訊息傳送, 基於Google ProtoBuf自定義的訊息協議, TCP粘包/拆包.... 客戶端通過TCP連線到伺服器,並建立TCP長連線;當伺服器端收到新訊息後通過TCP連線推送給

Android訊息(二)--基於MQTT協議實現的功能

前段時間公司需要android端的手機群推功能,我們就通過MQTT來實現了該功能。 MQTT的官網如下 http://mqtt.org/ 關於系統的主要架構就不詳述了。這關係的到職業道德問題,在這裡

Android訊息的Androidpn實現方式:(一)下載androidpn伺服器端與客戶端的Demo並執行

androidpn是基於XMPP協議的用於向Android客戶端推送文字資訊的一套開源的工具。它幫我們做了那些維護Socket長連線等等的事情。  在真正把它使用在我們的專案中之前,我們先領略一下推送。 第二步,啟動伺服器端與客戶端,通過Web頁面推送。詳細的步驟如下:

Android 訊息:個

之前一直在使用極光推送,這次專案打算使用個推試試!整合失敗原因:1、檢查自己的APPID等資訊2、檢查自己的.jar和.so檔案3、檢查AndroidManifest.xml<!-- 自定義許可權 自定義許可權解釋:部分手機型號不能正常執行個推SDK,需新增自定義許可權

android socket通訊demo (本篇服務於android訊息

本文系作者原創,轉載請附原文地址,謝謝。 文章末尾提供本文中的原始碼下載連結,需資源積分1分,人艱不拆,下載後評論資源可獲系統返回積分=無損! 前言: 關於什麼是socket通訊,本篇文件中不進行解釋,不甚清楚的可以去百科查詢,日後得空我也會整理相關的內容。 本文

Android訊息接收後,通知欄的顯示

訊息推送接收到後,顯示通知欄 public static void showNotifictionIcon(Context context) { NotificationCom

android訊息(二)之——XMPP協議

XMPP協議 XMPP協議,中文名為可擴充套件通訊和表示協議,是一種以XML為基礎的開放式實時通訊協議,它將需要實時通訊的訊息嵌入到XML結構體中,不僅具有很好的可擴充套件性,還有較強的可讀性。 XM

Android訊息(廣播機制)+通知

Android廣播機制使用了觀察著模式; (1) 通知 1) 獲取狀態通知欄管理 NotificationManager 是一個系統Service,所以必須通過getSystemService(NO

Android 訊息(notification) 標題欄icon不顯示內容

今天做專案遇到一個奇葩的問題,如下圖: 標題欄不顯示icon內容,網上找了半天還是沒有解決這個問題,後面用黑白的icon解決這個問題 這個問題不曉得是不是Android 5.0的原因,或者有朋友已經解決問題的能否告知一下

Android訊息完美解決方案

1.推送方式基礎知識:   在移動網際網路時代以前的手機,如果有事情發生需要通知使用者,則會有一個視窗彈出,將告訴使用者正在發生什麼事情。可能是未接電話的提示,日曆的提醒,或是一封新的彩信。推送功能最早是被用於Email中,用來提示我們新的資訊。由於時代的發展和移動網際網

Android 基於Netty的訊息方案之物件的傳遞(四)

在上一篇文章中《Android 基於Netty的訊息推送方案之字串的接收和傳送(三)》我們介紹了Netty的字串傳遞,我們知道了Netty的訊息傳遞都是基於流,通過ChannelBuffer傳遞的,那麼自然,Object也需要轉換成ChannelBuffer來傳遞。好在Netty本身已經給我們寫好了

Android 基於Netty的訊息方案之字串的接收和傳送(三)

在上一篇文章中《Android 基於Netty的訊息推送方案之概念和工作原理(二)》 ,我們介紹過一些關於Netty的概念和工作原理的內容,今天我們先來介紹一個叫做ChannelBuffer的東東。 ChannelBuffer  Netty中的訊息傳遞,都必須以位元

Android 基於Netty的訊息方案之概念和工作原理(二)

上一篇文章中我講述了關於訊息推送的方案以及一個基於Netty實現的一個簡單的Hello World,為了更好的理解Hello World中的程式碼,今天我來講解一下關於Netty中一些概念和工作原理的內容,如果你覺得本篇文章有些枯燥,請先去閱讀《Android 基於Netty的訊息推送方案之Hell

android 實現mqtt訊息,以及不停斷線重連的問題解決

前段時間專案用到mqtt的訊息推送,整理一下程式碼,程式碼的原型是網上找的,具體哪個地址已經忘記了。 程式碼的實現是新建了一個MyMqttService,全部功能都在裡面實現,包括連伺服器,斷線重連,訂閱訊息,處理訊息,釋出訊息等基本操作。 首先新增依賴: dependencies { &

Android UDP - 簡單訊息功能

近期接觸了幾個小的Android開發專案,根據需求要利用到網路傳輸中的UDP協議方式傳輸,遇到不少坑,在此分享一下在Android應用中UDP的一些簡單技術功能實現,希望能幫到用得到的同僚。 需(wo)求(yao)分(gan)析(ma): 從PC上輸入一串亂七八糟,然後能在我手機(某為pow

Android安卓狀態列訊息通知(Notification)

我從不猜測,猜測是一個很壞的習慣——會影響正常的邏輯推理能力。              ——阿瑟·柯南·道爾 《福爾摩斯探案集》 近日,在做安卓專案開發的時候涉及到狀態列通知的需求,查了資料,總結一個簡

Android開發-在Android應用裡整合友盟訊息SDK的實現(相容小米、華為、魅族機型離線

前 言 最近由於專案的功能需求的需要,需要在Android應用整合訊息推送的功能,而目前市面上的第三方訊息推送除了友盟推送外,還有極光推送、小米推送、個推以及信鴿(騰訊)推送等。當時本人對比各大第三方的訊息推送進行了測試,覺得友盟訊息推送整合簡單,推送訊息的

Android MQTT 訊息demo

··· 不會轉換gif格式,截圖給你們看看吧,如果有好的免費的轉換工具可以留言推薦給我,在此衷心感謝 裡邊寫了好多註釋,應該都能看懂,這個在ssm專案中也可以使用但需要定製,去除android化的東西 ··· 1.介面 2.連線Mqtt 3.傳送和接收訊息(上邊

Bmob 開發 Android程式快速入門 10 訊息

                             Bmob 開發 Android程式快速入門 10 訊息推送