<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Jack Jiang

    我的最新工程MobileIMSDK:http://git.oschina.net/jackjiang/MobileIMSDK
    posts - 494, comments - 13, trackbacks - 0, articles - 1

    前言

    Android進程和Service的保活,是困擾Android開發人員的一大頑疾。因涉及到省電和內存管理策略,各廠商基于自家的理解,在自已ROOM發布于都對標準Android發行版作為或多或少的改動,使得應用層程序在處理進程和Service保活問題上變的異常復雜,且很難兼容,因為說不定哪款手機或者哪個版本的省電策略發生改變,那么隨之而來的就是進程和Service保活的差異。

    在應用場景上,由于即時通訊應用(包括IM聊天應用、消息推送服務等)為了保證消息的全時、實時送達能力,必須要實現進程或Service的保活。而就這一看似不起眼的問題,實際處理起來,因為眾多Android手機和Android系統版本的差異,讓問題的處理充滿了不確定性。

    本文基于作者的實踐以及相關資料的整理,總結了自已對Android進程和Service保活的理解,希望能為你的應用開發帶來啟發。(本文同步發布于:http://www.52im.net/thread-429-1-1.html

    學習交流

    - 更多即時通訊技術資料:http://www.52im.net/forum.php?mod=collection&op=all

    - 即時通訊開發交流群: 215891622 [推薦]

    概述

    近期做了一個Android項目,涉及到了后臺進程和Service保活的問題,網上找了很多資料,基本的保活方法都測試了。結果是:不同的手機,不同的Android版本保活效果各有差異。最難繞過的是個廠商對“后臺程序保活”管理。

    本文主要把相應的實踐結果和保活方法進行總結。然而,因筆者可用的測試真機有限,可能存有不完整的地方,還請及時提出指正并補充,大家共同進步。

    手機QQ、微信這樣的大型IM是如何解決保活問題的?

    以小米手機為例,MIUI的神隱模式讓很多IM和推送開發同行糾結不已:在MIUI深度休眠之后,默認會徹底斷開后臺應用的socket。但微信、QQ這樣的應用,MIUI官方的帖子說了:給這2個應用特殊照顧。好吧,特殊照顧,普通的APP只能繼續折騰了。

    (關于MIUI的神隱模式的討論,見此貼的回復:http://www.52im.net/thread-354-1-1.html

    本文實踐涉及到的真機型號和版本

    手機:三星9100-4.1.2,三星9300-4.3,華為G730-4.1.2,華為TL00H-EMUI3.1(android 5.1.1),魅族MX4-Flyme4.2.8.2c(android 4.4.2)。

    手頭能用的測試機就這些了。主要測試的service是一個最基本的service,在相應的生命周期的觸發函數上做了輸出。測試時都沒有添加到后臺保護中,注:三星的機子沒找到有后臺保護設置的地方。

    為什么我們的后臺進程/Service會被結束掉?

    我想到的是有三個方面:

    • Android系統內存回收機制;
    • 各廠商對后臺程序的一個管理制度(就是允許程序后臺運行那個);
    • 第三方軟件的清理(360什么的)。


    其中有的后臺程序保護把程序結束的同時會把程序弄成停止狀態,導致無法接收廣播!

    我們的保活方案有哪些?

    1)控制onStartCommand函數的返回值:

    我對這個函數的理解是:當服務被異常終止時,是否重啟服務?有些文章里面在用這個做保活時,修改的是flag,在我實際測試中是無效。有效的做法是直接返回參數。另外默認的flags值為0,是START_STICKY_COMPATIBILITY。

    具體代碼如下:

    1
    2
    3
    4
    5
    6
    @Override
    publicintonStartCommand(Intent intent,intflags,intstartId) {
        // TODO Auto-generated method stub
        returnSTART_STICKY;
        //return super.onStartCommand(intent, flags, startId);
    }


    測試結果:
    魅族的機子無效,不管默認還是修改參數,在DDMS里面直接結束進程后都不會重啟服務。其它三臺機子(9100沒測):默認參數的情況下就會重啟服務,return START_STICKY 會重啟,return START_NOT_STICKY 不會重啟。

    另外:用360一鍵清理,或者360超級ROOT的手機優化,會殺死進程,過會兒還是會重啟,只是會慢很多,大概是在排隊重啟服務。

    2)在service 的onDestory里面重啟服務:

    這個在所有能觸發onDestory的情況下都是有效的。4臺測試機都測試過。直接startService 或者發送廣播重啟都可以 。

    但能觸發onDestory的情況,我不知道內存回收會不會觸發。另外兩種情況(2,3)是不觸發的。我的測試方法是在“設置”-> 應用管理-> 正在運行-> 停止服務。(這個是正常停止服務,會觸發onDestory,所以上面的onStartCommand效果不會觸發。)

    3)提高服務的優先級:

    這個主要是針對第一種kill服務的情況,內存回收機制。由于這個測試比較難搭建。360清理什么把后臺的進程都殺的,體現不出優先級這樣的概念。我的建議是能提高就提高,下面幾個實驗。

    [1] 前臺service:
    創建一個通知使自己成為前臺service
    測試結果:
    360一鍵清理和手機優化,不會把該service結束掉。

    [2] 對于后臺保護:
    華為G730不結束service,魅族和華為TL00H都會結束service。通知欄的保活效果還是可以的,一般的應用要求基本能滿足了。

    [3] 若有root權限:
    android:persistent="true",并放入system/app中
    測試結果:
    效果一般,三星9100上用360等清理工具殺不掉進程,在華為G730上沒什么效果.(這個測試跟onStartCommand有點干擾)。

    4)守護進程:

    雙服務:360會同時殺掉兩個服務,分兩個apk也一樣。
    native守護進程:360不會殺掉native的守護進程,但在魅族和華為TL00H中待機一段時間后還是會被殺掉。

    結論和待續:
    1. 一般的應用添加到后臺保護進程后,改個onStartCommand返回值,再加個通知。基本上大部分都能保活了。
    2. 雙服務我覺得沒有native守護進程來的好,雖然360,微信什么的都有幾個進程服務,但如果不添加到后臺保活的話,效果一樣不能保活,也會進入停止狀態。
    3. 但是.360手機助手會創建雙natice守護進程做相互的看守。存活的效果會高一點點。“沒添加到后臺保活”一般只會殺一次,(魅族是屏幕關閉后5分鐘,華為TL00H是屏幕關閉時)。

    附個native守護進程:利用socket來判斷服務是否存在,需要在被保活的服務里創建一個監聽socket。調試信息會在SD卡目錄下創建一個daemon.log。使用方法:NDKFork port包名/.服務名。具體下載鏈接:
    http://download.csdn.net/detail/pvlking/9412815

    Android應用實現保活的基本原理總結

    都是通過雙進程互拉以及設置進程的重要性,除非你root后,把自己的進程設置成系統進程。

    互拉的方式有很多種:

    • 可以通過監聽系統廣播來把自己拉起來
    • 可以多個app相互拉
    • 可以把自己的服務搞成前臺服務
    • 在service的onstart方法里返回 STATR_STICK
    • 添加Manifest文件屬性值為android:persistent=“true”
    • 覆寫Service的onDestroy方法
    • 服務互相綁定
    • 設置鬧鐘,定時喚醒
    • 自己的app在native層fork一個子進程來與主進程互拉。


    綜上所述,總結下來就是,目前實現Android后臺保活沒有完美實現,只能針對不同的機型綜合使用上面列舉的方法,同時祈禱自已APP的用戶不要遇到奇葩機型的保活問題。

    推薦一個開源的解決方案 

    1)源碼托管地址

    源碼托管地址是:https://github.com/52im/MarsDaemon

    2)實現原理

    原理:使用Jni,在 c端 fork進程,檢測Service是否存活,若Service已被殺死,則進行重啟Service.  至于檢測方式,可以輪詢獲取子進程Pid,若為1, 則說明子進程被Init進程所領養,已經成為了孤兒進程.    但是這種方式比較消耗電量,并且由于不同手機系統定制的改變,當應用被強制停止時,父進程并不一定被真正殺死,因此在一些特定機型上是無法通過此方式進行判斷. 這里推薦使用liunx socket的方式進行類似心跳包的檢測,并且當觸發檢測Service是否被殺死之前,需要判斷應用是否已經被卸載,如果應用已經被卸載,則不再進行檢測Service行為,直接調用exit(0)退出子進程,避免浪費系統資源和消耗電量.

    注意: 目前在Android 5.0系統上會把fork出來的進程放到一個進程組里, 當程序主進程掛掉后,也會把整個進程組殺掉,因此用fork的方式也無法在Android5.0及以上系統實現守護進程. 這個是系統層面的限制,當然也是為了優化整個的系統環境,守護進程給手機帶來的體驗并不好

    具體見源碼:
    http://androidxref.com/5.0.0_r2/ ... /ProcessRecord.java
    Android后臺保活實踐總結:即時通訊應用無法根治的“頑疾”_1809710-8f67dfa36f847c43.png 

    好消息:
    Android5.0 以上目前已在 https://github.com/52im/MarsDaemon 中被黑科技攻克,部分機型可能無法起到作用,但思路很值得借鑒,代碼結構也不錯, 具體方案請見源碼哦。

     

    (本文同步發布于:http://www.52im.net/thread-429-1-1.html

    作者:Jack Jiang (點擊作者姓名進入Github) 
    出處:http://www.52im.net/space-uid-1.html 
    交流:歡迎加入即時通訊開發交流群 215891622 
    討論:http://www.52im.net/ 
    Jack Jiang同時是【原創Java Swing外觀工程BeautyEye】【輕量級移動端即時通訊框架MobileIMSDK】的作者,可前往下載交流。
    本博文 歡迎轉載,轉載請注明出處(也可前往 我的52im.net 找到我)。 



    作者:Jack Jiang (點擊作者姓名進入Github)
    出處:http://www.52im.net/space-uid-1.html
    交流:歡迎加入即時通訊開發交流群 215891622
    討論:http://www.52im.net/
    Jack Jiang同時是【原創Java Swing外觀工程BeautyEye】【輕量級移動端即時通訊框架MobileIMSDK】的作者,可前往下載交流。
    本博文 歡迎轉載,轉載請注明出處(也可前往 我的52im.net 找到我)。


    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    Jack Jiang的 Mail: jb2011@163.com, 聯系QQ: 413980957, 微信: hellojackjiang
    主站蜘蛛池模板: 亚洲欧美aⅴ在线资源| www在线观看免费视频| 67194国产精品免费观看| 亚洲香蕉成人AV网站在线观看| 无码天堂亚洲国产AV| 两个人看的www免费| 4虎永免费最新永久免费地址| 亚洲av综合色区| 一级毛片免费视频网站| 免费萌白酱国产一区二区| 国产精品亚洲一区二区在线观看| 国产精品嫩草影院免费| 婷婷亚洲综合五月天小说在线| 免费一级毛片不卡不收费| 免费一级特黄特色大片| 性感美女视频在线观看免费精品| 成人亚洲国产va天堂| 色吊丝永久在线观看最新免费| 爱情岛论坛亚洲品质自拍视频网站| 国产精品成人无码免费| WWW国产成人免费观看视频| 国产黄色片在线免费观看| 校园亚洲春色另类小说合集| www国产亚洲精品久久久日本| 在线观看免费黄色网址| 亚洲AV一宅男色影视| 无码精品A∨在线观看免费| 久久亚洲精品中文字幕| 免费在线视频你懂的| 亚洲码欧美码一区二区三区| 免费一级毛片一级毛片aa| 全黄大全大色全免费大片| 亚洲国产美女福利直播秀一区二区 | 亚洲精品午夜无码专区| 97公开免费视频| 亚洲欧美国产国产一区二区三区| 亚洲午夜精品第一区二区8050| 国产精品99精品久久免费| 亚洲精品无码Av人在线观看国产| 91青青青国产在观免费影视| 亚洲av综合av一区二区三区|