微信團隊原創分享:Android版微信後臺保活實戰分享(程式保活篇)
http://www.52im.net/thread-210-1-1.html
哪些部分需要“保活”?
按照我們的理解包含兩部分:
- 網路連線保活:
如何保證訊息接收實時性。詳見本文上篇《微信團隊原創分享:Android版微信後臺保活實戰分享(網路保活篇)》 - 程式保活:
儘量保證應用的程式不被Android系統回收。這是本文要討論的內容。
程式保活概述
在Android系統裡,程式被殺的原因通常為以下幾個方面:
- a. 應用Crash
- b. 系統回收記憶體
- c. 使用者觸發
- d. 第三方root許可權app.
原因a可以單獨作為一個課題研究。原因c、d目前在微信上沒有特殊處理。這裡討論的就是如何應對Android Low Memory Killer。
程式保活實施:程式拆分
上圖表述的是微信主要的幾個程式:
- a. push主要用於網路互動,沒有UI
- b. worker就是使用者看到的主要UI
- c. tools主要包含gallery和webview
拆分網路程式,確實就是為了減少程式回收帶來的網路斷開。
可以看到push的記憶體要遠遠小於worker。而且push的工作性質穩定,記憶體增長會非常少。這樣就可以保證,儘量的減少push 被殺的可能。這裡有個思路,但限制比較多,也拋磚引玉。啟動一個純C/C++ 的程式,沒有Java run time ,記憶體使用極低。
這種做法限制很明顯,如:沒有Java run time ,所以無法使用Android系統介面。缺乏許可權,也無法使用各種shell命令操作(如am)。但可以考慮一下用途:高強度運算,網路連線,心跳維持等。比如Shadowsocks-android就如此,通過純c命令列程式,維護著socks5代理 (Android M執行正常)。
tools程式的拆分也同樣是記憶體的原因:
- a. 老版本的webview 是有記憶體洩漏的
- b. Gallery大量縮圖導致記憶體使用大
微信在進入後臺後,會主動把tools程式kill掉。
程式保活實施:及時拉起
系統回收不可避免,及時重新拉起的手段主要依賴系統特性。從上圖看到, push有AlarmReceiver, ConnectReceiver,BootReceiver。這些receiver 都可以在push被殺後,重新拉起。特別AlarmReceiver ,結合心跳邏輯,微信被殺後,重新拉起最多一個心跳週期。
而對於worker,除了使用者UI操作啟動。在接收訊息,或者網路切換等事件, push也會通過LocalBroadcast,重新拉起worker。這種拉起的worker ,大部分初始化已經完成,也能大大提高使用者點選微信的啟動速度。
歷史原因,我們在push和worker通訊使用Broadcast和AIDL。實際上,我一直不喜歡這裡的實現,AIDL程式碼冗餘多, broadcast效率低。歡迎大家分享更好的思路或者方法。
程式保活實施:程式優先順序
Low Memory Killer 決定是否殺程式除了記憶體大小,還有程式優先順序:
上表的數字可能在不同系統會有一定的出入,但明確的是,數值越小,優先順序越高。對於優先順序相同的程式,總是會把記憶體佔用多的先kill。提高程式優先順序是保活的最好手段。
正常情況下微信的oom_adj:
而被提高優先順序後:
從統計上報看,提高後的效果極佳。原理:Android 的前臺service機制。但該機制的缺陷是通知欄保留了圖示。
對於 API level < 18 :呼叫startForeground(ID, new Notification()),傳送空的Notification ,圖示則不會顯示。對於 API level >= 18:在需要提優先順序的service A啟動一個InnerService,兩個服務同時startForeground,且繫結同樣的 ID。Stop 掉InnerService ,這樣通知欄圖示即被移除。
這方案實際利用了Android前臺service的漏洞。微信在評估了國內不少app已經使用後,才進行了部署。其實目標是讓大家站同一起跑線上,哪天google 把漏洞堵了,效果也是一樣的。
QA環節
Q:之前看微信的架構分享,貌似是通過單一Activity,用多個Fragment切換來實現的多視窗。如果分程式的話,看起來Gallery和
WebView是單獨的一個Activity,我的理解是否正確呢?以及進入後臺之後,為何只kill tools而不一起釋放work呢?
A:Fragment的改造只是用在有限的幾個UI上,大部分的UI,對於切換時間要求不高,還是保留成activity,Gallery和WebView都是單獨的
activity,所以才可能另外一個程式的。對於我們來說worker的保活僅次於網路的push,worker如果頻繁被殺,使用者每次啟動微信都需要
等待,這個就不好了。所以,我們在後臺,只會kill tools,不會主動kill worker。
Q:除了提高程式的優先順序,微信在記憶體方面有什麼處理或優化的技術嗎?
A:不可否認,其實微信是記憶體大戶了,現階段我們主要關注記憶體洩漏,沒有專門去減少記憶體的使用,畢竟記憶體意味著cache,意味著使用者體驗更快,後續對於記憶體優化我們有一些規劃,比如說,在cache這塊照顧一些低端機。
Q:我記得很久以前聽說過微信使用一個畫素的浮動視窗來保活,不知道現在還有沒有呢?
A:我們有想過,也聽說過有其他app是這樣做的,但從來沒實現過這個方案。
Q:你們push程式與worker程式採用過socket通訊方案麼?採用的話效果怎麼樣?
A:有考慮過用socket,後續也可能會有這種嘗試,但因為push和worker依賴程式碼太多,傷筋動骨了,但估計也要比AIDL好,AIDL對於應用出問題後能做的事情太少了。
相關文章
- 微信團隊原創分享:iOS版微信的記憶體監控系統技術實踐iOS記憶體
- 微信群活碼以及微信活碼防封如何實現技術分享
- 微信後團隊分享:微信後臺基於Ray的分散式AI計算技術實踐分散式AI
- 微信團隊分享:微信後臺在海量併發請求下是如何做到不崩潰的
- android微信分享、微信支付的一些坑Android
- 微信分享
- 國慶節微信公眾號活動分享,如何做好十一國慶節微信公眾號活動
- 實現微信分享功能
- Android 微信分享後留在微信,沒有回撥的問題解決方案Android
- Flutter Notes | Android 借殼分享微信FlutterAndroid
- Cocos Creator - 微信小遊戲 實戰分享遊戲
- 微信後臺開發實戰教程
- 微信活碼系統程式原始碼原始碼
- Android應用保活實踐Android
- 微信團隊分享:微信移動端的全文檢索多音字問題解決方案
- 玩Android微信小程式版Android微信小程式
- 實體店怎麼做微信行銷推廣?分享引流進店的微信抽獎活動製作教程
- 微信分享 - 開荒
- 微信語音分享
- Android之APP保活AndroidAPP
- 微信分享筆記(第二版)筆記
- 記一次微信分享前後端實現後端
- Android8.0 後臺服務保活的一種思路Android
- 微信app支付 java後臺接AndroidAPPJavaAndroid
- VUE專案微信分享Vue
- 微信小程式之分享海報生成微信小程式
- 分享為什麼不加微信分享呀
- Android 無需申請key直接呼叫微信/QQ/微博分享Android
- 微信JSSDK遇見的坑--vue微信自定義分享JSVue
- 品牌“雲保護”!微信品牌保護團隊與40家品牌線上交流,共同打擊侵權造假
- 微信域名檢測 微信域名檢測官方介面的呼叫程式碼分享
- “微工卡+靈工保險”逐漸普及 微信支付助力保障靈活就業群體權益就業
- uni-app 微信小程式全域性分享APP微信小程式
- uniapp h5微信分享APPH5
- APICloud分享圖片到微信APICloud
- 微信分享(移動web端)Web
- 微信分享測試步驟
- 微信域名檢測實現機制與程式碼分享