近日在網上看到一個文章,介紹 iPhone、Android 上的熱門的 VOIP 應用 Viber ,曰:
它可以完全運行在后臺,且不會耗電,即便是不運行在后臺,你照樣可以撥打免費電話和發免費短信。
應該說,這些說法從技術上看并不嚴謹。首先,從這段文字能得到一個模糊的印象,一個在后臺運行的程序,并且不會耗電;其次,“程序即便是不運行在后臺,照樣可以撥打免費電話和發短信”,這如何理解呢?程序運行在前臺能否撥打免費電話?程序壓根不運行時能否撥打電話?
VOIP 應用是一種必須實現為“多任務”的業務,這種業務通常是耗電的大戶。因此這段文字背后引出其中一個有趣的技術問題,智能設備上的多任務的業務如何能夠“不會耗電”?
讓我們先看看智能手機上的電池電量限制與多任務需求的關系。
智能手機上電池電量限制與多任務需求
智能手機與桌面電腦的根本區別在于智能手機本身的硬件尺寸與電池電量大小,電池電量對智能手機來說是關鍵而致命的限制,人們要求手機越來越輕薄,功能越來越強大,然而待電時間卻要求越來越長,這不是“又要馬兒跑又要馬兒不吃草”的事情么!為此,智能手機上的電池電量正如沙漠中的水,一點一滴都不可以浪費。
為了節約電池的電量,智能手機上的操作系統的一個基本策略是,盡量減少正在運行的程序,這個道理很簡單,運行的程序越多,需要耗費的 CPU 計算時間就越多,電量就省不下來。下面的圖是蘋果iOS 設備應用程序調度狀態圖,事實上蘋果設備是除了用戶正在操作的程序,其他打開的程序進程盡可能都放到“掛起(Suspended)”的狀態下。在“掛起”的狀態下面,程序進程處在休眠狀態,不耗費 CPU 計算能力。當用戶沒有對設備進行操作的時候,整個系統處在休眠的低電狀態。(這里進程的意思是:程序運行實例)
智能手機上的 VOIP,作為一種多任務型的業務,卻恰恰踩在耗電的雷區上。VOIP 類的應用需要實現為多任務原因是需要維持應用應用與服務器之間的長期的網絡連接,當網絡側的來電呼叫到達的時候,提示用戶進行接聽。因此程序有“長期存活”的“待機”需求,后臺長期存活的程序僅僅能處在“后臺(Background)”的狀態下面,這個狀態下的程序進程,需要耗費 CPU 計算能力和電量。為何叫做“多任務”型的業務呢,意思是由于此業務的存在,除了用戶交互的程序進程,還存在另外的“存活”進程。
蘋果 iOS 設備的 VOIP 實現
正是由于對程序耗電量的錙銖必較,蘋果公司曾經拒絕實現“真正”的多任務,使用“快速程序切換”來緩解用戶對大部分“多任務”的需求,如今,相信蘋果的研發團隊是在做了艱難的平衡之后,決定允許部分業務實現為“多任務”。這些業務主要是上文提到的后臺的音樂播放、后臺的 GPS 定位服務、新聞訂閱業務的后臺定期更新、VOIP 應用等等,并為后臺業務實現提供嚴格的開發指引。VOIP類的業務正是蘋果公司強制管理的一種“多任務”業務,如果開發團隊不遵守架構限制,軟件將不能通過審核和在蘋果應用商城上發布,而 Viber,在 iOS 平臺上,應該是遵循了該架構。
讓我們來看看蘋果公司為VOIP實現,這種架構下如何可能達到省電的目標。
下面描述的文字非開發指引,僅僅為了幫助理解 VOIP 應用進程的調度過程(需要一定的軟件開發背景來理解):
1、VOIP 應用需要在 Info.plist 里配置 UIBackgroundModes 的值為 “VOIP” ,告知系統,此乃 VOIP 應用。
2、程序配置用于 VOIP 業務的網絡連接(Socket),告知系統,在程序進程被調度到“掛起(Suspended)”狀態時該特殊的網絡連接需要被系統接管,因此,此時網絡連接仍然是活動的。當網絡連接有新的數據到達的時候,程序將從“掛起(Suspended)” 狀態被喚醒到“后臺 (Background)”狀態,如果是個來電事件,VOIP應用則發起一個本地提醒事件,此時用戶可以在設備的界面上看到來電提醒,如果用戶選擇接聽來電,則 VOIP 應用被調度到前端的“活動 (Active)”狀態直接與用戶交互,否則,回退到低電的“掛起(Suspended)”狀態。下圖可以看到左圖是傳統的 VOIP 應用,在“待機”狀態下整個程序都運行在耗電的“后臺 (Background)”狀態,右圖是蘋果的 VOIP 實現,僅僅網絡連接運行在耗電的“后臺 (Background)”狀態。其余系統部分運行在低電的“掛起(Suspended)”狀態。
3、安裝 Keep-Alive 的處理函數維持與服務器端的長連接。VOIP應用將被周期性從“掛起(Suspended)”狀態調度到“后臺 (Background)”,使 Keep-Alive 的處理函數能夠定期向網絡服務器發送“心跳”的網絡包。
總結:在 iOS 實現的 VOIP 方案中,應用進程可以看作兩部分,一部分是需要系統內核看管的網絡連接和系統的定期喚醒服務,另一部分是 VOIP 的程序邏輯,在 VOIP 的狀態下,后一部分被放到了低電的“掛起(Suspended)”狀態,最少的使用了 CPU,因此可以達到省電的效果。
為何能夠更省電
然后,回到關于Viber的問題,如何“程序即便是不運行在后臺,照樣可以撥打免費電話和短信”?據考究,實際上應為“即便程序不運行,照樣可以接聽電話和短信”。原因是,撥打電話和短信,肯定必須有用戶的交互操作,程序只能處在“活動(Active)狀態”,不可能是不運行的。根據Viber的網站的資料,Viber 使用了蘋果的 APNs(Apple Push Notification Service)功能,當用戶有電話撥入或者短信發送過來的時候,此時才加載 Viber 應用。APNs 服務是一種 Apple 公司的網絡端服務,用來向蘋果設備推送消息,通常也用來實現郵件推送等功能。
當然,使用 APNs 的方式提醒用戶來電和短信,可以更加省電,在“待機”期間,Viber 程序可以根本沒有運行,僅僅當有來電和短信的時候借用了系統提供的 APNS 服務來喚醒和加載應用。
終極的省電方式
當然,無論如何優化,這種 VOIP 應用相比起傳統語音實現來說仍然是耗電的,因為整個系統(智能手機的 AP 部分)不能休眠。在傳統的非 VOIP 話音業務中,如果沒有來電和用戶操作,整個系統是休眠的,僅僅是基帶芯片(智能手機的 CP 部分)在工作,負責維護與電信運營商基站的連接,這無疑是最省電的一種工作方式。