首先,先擱下幾個問題,什么是進程?;睿繛槭裁匆羞M程?;睿孔詈蟛攀沁M程?;钜趺磳崿F(xiàn)??相信大家會迫不及待跳到最后一個問題去看保活要怎么實現(xiàn),可本文致力于為新手鋪路,保駕護航。
一、什么是進程?;??
一開始接觸到這個的時候,我是覺得太高大上了,android進程是什么東西,一個應(yīng)用就是一個進程嗎?NoNoNo,圖樣圖森破,這是我剛畢業(yè)的時候還有的想法。之前的說android一個應(yīng)用可以有多個進程,簡稱應(yīng)用內(nèi)多進程,當(dāng)然,在這里沒必要擴展,擴展的話就涉及到linux的知識了。那么到這里可能對于新手級(對這方面沒有接觸的朋友們)一切都還是懵逼的,其實簡單點來說,我們打開手機的應(yīng)用管理,就可以看到正在運行的應(yīng)用有

我們可以看到QQ跟微信明明我們只是打開了一次,但是卻顯示有多個進程跟服務(wù),這里我們看到的就是進程?;盍?,通過一個進程來讓應(yīng)用服務(wù)常駐后臺,即使用戶不打開應(yīng)用,也要背著用戶搞小動作的猥瑣行為,就是我們常說的進程?;盍?。而進程?;畹淖罡呔辰缇褪菍崿F(xiàn)在不同android系統(tǒng)上都能夠永生不死。當(dāng)然了,可能有大牛會說,別逗,不存在永生不死的進程,什么進程都可以kill掉,這里指的永生不死是用戶接受范圍內(nèi)的常駐后臺,如果用戶真的很不開心,另辟蹊徑也要殺掉進程,就別起來了,等到合適的契機再重啟吧,不然會被定位為流氓軟件的。

二、為什么要有進程?;睿?/h4>
最近項目中加入了推送的功能,之前的推送都是基于定時器,輪詢實現(xiàn)的,這個不用大家評論都只知道輪詢肯定是耗費資源的,雖然我不知道具體會耗費多少的資源,會做多少的無用功,但用推送代替輪詢,不管從哪方面考慮都是極好的。言歸正傳,先說一下最近對推送功能的感悟(吐槽一下國內(nèi)用不了google的推送功能,感嘆一下websocket全雙工的微妙),一般來說,我們的應(yīng)用都需要推送!!為什么呢?因為如果沒有推送的話,那么一切的會話都變成從客戶端發(fā)起的,因為http的局限,而我們大多數(shù)的應(yīng)用都是基于http進行網(wǎng)絡(luò)交互的,所以,推送就成了提高用戶體驗,為app與用戶之間創(chuàng)造了更多交互機會的橋梁了。不得不說,這個功能是我入行以來做過最贊的功能??!難度可以說是最簡單的,比登錄注冊還要簡單...推送服務(wù),就是一個我們需要?;畹倪M程,不然用戶殺掉APP,就沒有推送功能了,老板肯定不干啊,而且用戶本來的用意也不想接收推送啊,只是因為android的生態(tài)環(huán)境導(dǎo)致用戶養(yǎng)成了不使用就直接從后臺殺死應(yīng)用的習(xí)慣。

雖然用戶養(yǎng)成了這么壞的習(xí)慣,但是我們總不能在雙擊返回鍵退出的時候,再添加一個“為了推送功能不要從后臺殺死應(yīng)用”。所以,僅僅是為了正常的推送功能的實現(xiàn),我們就應(yīng)該讓進程能夠常駐后臺,也就是說進程?;盍?。殺了能重啟,殺了能重啟...
三、如何實現(xiàn)進程保活呢?
前面洋洋灑灑的吹了幾百字,終于到了重頭戲了。怎么實現(xiàn)進程保活呢?相信android剛出道的時候,android開發(fā)者還是很淳樸的,并沒有想要做流氓軟件,騷擾用戶這些破壞android生態(tài)環(huán)境的事。所以在網(wǎng)上有一大堆的實現(xiàn)所謂的進程保活的方法,由淺入深吧:
1、使用系統(tǒng)廣播來喚醒app服務(wù)
相信大家在學(xué)習(xí)android的時候,都會有一本android基礎(chǔ)的教科書,哈哈,想當(dāng)年我決定做android的時候,只看了一下java基礎(chǔ)就去面試騰訊的android實習(xí)崗位,也是蠻秀逗的啊。當(dāng)然,面試沒過...不過后來我仔細(xì)研究android基礎(chǔ)的時候,就發(fā)現(xiàn)靜態(tài)注冊的廣播接收器,也就是在AndroidManifest.xml文件里面配置的receiver,任何時候都能夠接收廣播進行處理,這樣的話,就產(chǎn)生了方法1,我們可以借助系統(tǒng)廣播來打開我們app的后臺服務(wù),比如
android.intent.action.ACTION_TIME_TICK
android.intent.action.USER_PRESENT
android.intent.action.PRE_BOOT_COMPLETED
...
如果你認(rèn)為一切都是這樣的簡單,那就真的是圖樣圖森破了,網(wǎng)上大多數(shù)的關(guān)于進程自啟動,進程保活的資料都是使用的這個方法,當(dāng)我們滿心期待地想要實現(xiàn)這個“簡單”的功能時,就會發(fā)現(xiàn),教科書講大話!廣播接收器并沒有接收到廣播,說好的在清單文件中注冊廣播接收器就能夠接受全局廣播的呢?我也在這里糾結(jié)了很久,曾經(jīng)一度沮喪說android的教科書太氣人了,竟然蒙騙我這種新手。后來經(jīng)過多番研究,發(fā)現(xiàn)在android3.1之后,使用了新的廣播機制,該平臺定義了兩個新的Intent的Flag,讓發(fā)送者指定的意圖是否應(yīng)該被允許激活停止的應(yīng)用程序的組件。分別為
FLAG_INCLUDE_STOPPED_PACKAGES 包括停止的應(yīng)用
FLAG_EXCLUDE_STOPPED_PACKAGES 不包括停止的應(yīng)用
當(dāng)兩個Flag都不設(shè)置或都設(shè)置的時候,默認(rèn)操作是FLAG_INCLUDE_STOPPED_PACKAGES。包含停止的應(yīng)用。
而問題就出在這里了,android3.1之后,系統(tǒng)在構(gòu)造系統(tǒng)廣播的intent時,向所有的Intent的廣播添加了FL??AG_EXCLUDE_STOPPED_PACKAGES標(biāo)志。它這樣做的目的就是避免壞的android開發(fā)者利用系統(tǒng)廣播瞞著用戶做一些壞事,比如開啟后臺服務(wù),要是每個應(yīng)用都開啟后臺服務(wù),并且在服務(wù)里面做一些聯(lián)網(wǎng),存取數(shù)據(jù)庫的操作,那么最直觀的就是我們的流量嘩啦啦的就花光了。這個改動既是為了安全,也是為了維護android的生態(tài)環(huán)境。
但是后臺服務(wù)或應(yīng)用程序仍然可以通過向廣播Intent添加FLAG_INCLUDE_STOPPED_PACKAGES標(biāo)志來喚醒處于停止?fàn)顟B(tài)(stopped state)的應(yīng)用程序。由此就引出了一種切實可行的實現(xiàn)進程保活的方法,利用第三方應(yīng)用來喚醒本應(yīng)用。
應(yīng)用程序處于停止?fàn)顟B(tài)有兩種情況,一種是他們是第一次安裝但還沒啟動,另一種是用戶在后臺進程管理手動殺死,處于后臺的應(yīng)用不殺死的話依然能夠接受到系統(tǒng)廣播。而系統(tǒng)級的應(yīng)用程序是可以接收到開機啟動廣播的,當(dāng)然了,系統(tǒng)級的應(yīng)用程序本身就受到特殊的待遇,更是可以通過配置android:process="persistent"來維護生命力!安裝在/System/App目錄下的應(yīng)用就視為系統(tǒng)級的應(yīng)用,相當(dāng)于身穿黃馬褂,手持免死金牌了,這種方法一般不作考慮。
2、偽進程?;?/p>
順帶說一下偽進程保活,為什么說是偽的呢?因為這種進程?;钗蚁刖褪菑V義上的雙進程守護,據(jù)說黑馬還是極光的每一期視頻都會有的課程就是雙進程?;睿俏蚁胨麄兊碾p進程?;钇鋵嵕褪抢脙蓚€服務(wù)互相拉起,當(dāng)然這只是我的猜測而已,我也沒看過他們的視頻,有機會一定要悄悄地搞一個回來學(xué)習(xí)一下...

這里說的這種進程保活,我也嘗試實現(xiàn)了一下,發(fā)現(xiàn)當(dāng)守護進程走生命周期的話,那么是可以實現(xiàn)互相拉起的,殺死了其中一個服務(wù),另一個服務(wù)就會重新把這個服務(wù)打開。之所以說偽,就是因為這種方法只是盡量維持后臺服務(wù):
如提升優(yōu)先級等,避免被系統(tǒng)殺死,在被系統(tǒng)殺死后能夠迅速活起來。
在onDestory發(fā)送廣播喚起自己
在onStartCommand中返回START_STICKY。。。等
然而要是用戶直接將后臺服務(wù)從進程管理中殺死的時候,那么這整一個Process就會被kill掉,這里進程的概念是相對于linux里面的一個進程,kill掉之后連帶這個應(yīng)用里所有的獨立進程都會被殺掉,這種時候,偽進程?;罹筒荒芑ハ嗬鹆?,因為都被殺死了,之前在網(wǎng)上看到有人說,白科技,灰科技,都是偽進程保活,而且利用系統(tǒng)漏洞實現(xiàn)的前臺服務(wù)更是在很多的手機上都不可行,前臺服務(wù)是可以提高服務(wù)的優(yōu)先級,但是用戶都看著呢,這明顯遵守?;畹拟嵲瓌t。雖然是偽的,我們?nèi)匀恍枰鲞@些保護措施,當(dāng)應(yīng)用沒有被用戶手動殺死的時候,維持后臺服務(wù)的正常運行。
3、黑科技環(huán)節(jié)
好像上面絮絮叨叨的,有的沒的說了一大堆,是時候介紹一些不明覺厲的東西了:
1.傳說中的鵝廠黑科技
在應(yīng)用退到后臺后,有一個1*1像素的頁面顯示在屏幕上,這種傳的神乎其技的東西也不知道真假,目前還沒看到有關(guān)于這方面的介紹或思路,盡管這種黑科技不能使進程永生不死,但是還是很有研究價值。
2.第三方SDK互相喚醒
我們在引用第三方SDK的時候,尤其是推送服務(wù),會有一個守護進程,雖然內(nèi)部實現(xiàn)不知道是什么原理,所以的數(shù)據(jù)走的都是一條鏈路,但是經(jīng)過鄙人一番狂妄的分析發(fā)現(xiàn),如果第三方sdk是基于ndk實現(xiàn)的進程守護,那么只要使用了這個sdk,就應(yīng)該能夠喚醒app才對,所以我想里面的守護進程只是為了守護推送服務(wù)能夠正常運行,而真正的互相喚醒是基于廣播機制的,由第三方應(yīng)用互相喚醒的方法。
3.ndk實現(xiàn)進程守護
github上傳聞有一個能讓進程在5.0上永生不死的demo,但是很多人使用了之后都說發(fā)生各種issues,而網(wǎng)上也有說利用一個native service來守護應(yīng)用層的service,實現(xiàn)所說的雙進程守護,ndk需要c++功底,而且還有通道這些,作為菜鳥的我尚未涉獵,但是相信這和github上的原理是差不多的。
4.奸商的暗箱操作
傳聞?wù)fQQ微信這些之所以能夠在各手機廠商生產(chǎn)的手機上常駐后臺,是歸根于廠商為了用戶體驗而與TX合作,讓QQ微信這些應(yīng)用進入白名單!諸如此類的app不少,不知道360是不是也是這樣子干的...
總結(jié)
總所周知的,老板把需求壓下來,我們苦逼程序員吧還是得撐住啊,所以真正適合我們苦逼程序員的解決方案有:
選用第三方SDK的時候盡量選用用戶量多的SDK(黑心可行,推薦)
在開發(fā)一系列APP的時候,讓APP之間能夠通過廣播相互拉起(工程量巨大,原理上可以實現(xiàn))
不過要是有大佬用ndk實現(xiàn)了進程的永生不死,煩請告訴小弟,即使我技術(shù)渣,但是我有一顆純真的赤子之心?。〖词褂眠@樣的黑科技,我們還是要致力于維護android的生態(tài)平衡啊。

最后的最后,能用錢解決的問題就不是問題哈