導航:首頁 > 操作系統 > android進程保活

android進程保活

發布時間:2022-09-21 21:12:31

❶ 盤點im即時通訊開發中android後台保活方案

對於IM應用和消息推送服務的開發者來說,在Android機型上的後台保活是個相當頭疼的問題。

老闆一句:「為什麼微信、QQ能收到消息,而你寫的APP卻不行?」,直接讓人崩潰,話說老闆你這APP要是整成微信、APP那麼牛,直接進手機廠商白名單,還要程序員在這瞎忙活?

好了,抱怨歸抱怨,活還得干,不然靠誰養活廣大苦逼的程序員?

正因為Android系統版本的差異,也導致了各種保活黑科技的運行效果大相徑庭,所以本文正好藉此機會,盤點一下當前主流(截止2019年前)的保活黑科技在市面上各版本Android手機上的運行效果,希望能給大家提供一些客觀的參考。

其實Android端APP搞保活的目的倒不是為了干什麼見不得人的壞事(但不排除動機不純的開發者),主要是像IM即時通訊應用和資訊類應用等需要搞後台消息推送、運動類應用需要在後台實時監測用戶的運動數據等,因為現在越來越多的手機廠商為了省電策略考慮,基本上如果你的應用沒有被加入白名單,一旦處於後台就會被系統限制甚至幹掉,但使用APP的用戶才不聽你這些解釋——反正「我」就要你的APP能如期正常運行,開發者也是不得已而為之。

以消息推送為例,當APP處於後台或關閉時,消息推送對於某些應用來說非常有用,比如:

    1)IM即時通訊聊天應用:聊天消息通知、音視頻聊天呼叫等,典型代表有:微信、QQ、易信、米聊、釘釘、Whatsup、Line;

    2)新聞資訊應用:最新資訊通知等,典型代表有:網易新聞客戶端、騰訊新聞客戶端;

    3)SNS社交應用:轉發/關注/贊等通知,典型代表有:微博、知乎;

    4)郵箱客戶端:新郵件通知等,典型代表有:QQ郵箱客戶端、Foxmail客戶端、網易郵箱大師;

    5)金融支付應用:收款通知、轉賬通知等,典型代表有:支付寶、各大銀行的手機銀行等;

      .... ....

在上述的各種應用中,尤其對於用戶接觸最多、最平常的IM聊天應用或新聞資訊來說,保活和消息推送簡直事關APP的「生死」,消息推送這種能力已經被越來越多的APP作為基礎能力之一,因為移動互聯網時代下,用戶的「全時在線」能力非常誘人和強大,能隨時隨地即時地將各種重要信息推送給用戶,無疑是非常有意義的。

題外話:實際上,對於後台消息推送能力,Android原版系統早就內置了系統級推送服務(跟iOS上的APNs服務是一個東西),它就是GCM服務(現在升級為FCM了),但眾所周之的原因,谷哥的服務在國內都是用不了的(你懂的)——無奈啊!

主要黑科技方案有:

    1)監聽廣播:監聽全局的靜態廣播,比如時間更新的廣播、開機廣播、解鎖屏、網路狀態、解鎖加鎖亮屏暗屏(3.1版本),高版本需要應用開機後運行一次才能監聽這些系統廣播,目前此方案失效。可以更換思路,做APP啟動後的保活(監聽廣播啟動保活的前台服務);

    2)定時器、JobScheler:假如應用被系統殺死,那麼定時器則失效,此方案失效。JobService在5.0,5.1,6.0作用很大,7.0時候有一定影響(可以在電源管理中給APP授權);

    3)雙進程(NDK方式Fork子進程)、雙Service守護:高版本已失效,5.0起系統回收策略改成進程組。雙Service方案也改成了應用被殺,任何後台Service無法正常狀態運行;

    4)提高Service優先順序:只能一定程度上緩解Service被立馬回收。 即時通訊聊天軟體app開發可以咨詢蔚可雲。

針對上述方案,具體的實現思路,通常是這樣的:

    1)進程拉活:AIDL方式單進程、雙進程方式保活Service(最極端的例子就是推送廠商的互相喚醒復活:極光、友盟、以及各大廠商的推送,同派系APP廣播互相喚醒:比如今日頭條系、阿里系);

    2)降低oom_adj的值:常駐通知欄(可通過啟動另外一個服務關閉Notification,不對oom_adj值有影響)、使用」1像素「的Activity覆蓋在getWindow()的view上(據傳某不可言說的IM大廠用過這個方案,雖然他們從未正面承認過)、循環播放無聲音頻(黑科技,7.0下殺不掉);

    3)監聽鎖屏廣播:使Activity始終保持前台;

    4)使用自定義鎖屏界面:覆蓋了系統鎖屏界面;

    5)創建子進程:通過android:process屬性來為Service創建一個進程;

    6)白名單:跳轉到系統白名單界面讓用戶自己添加app進入白名單。

使用AIDL綁定方式新建2個Service優先順序(防止服務同時被系統殺死)不一樣的守護進程互相拉起對方,並在每一個守護進程的ServiceConnection的綁定回調里判斷保活Service是否需要重新拉起和對守護線程進行重新綁定。

後台播放音樂這種保活方法,親身經歷過:

記得當時用的是某運動記步APP,它為了保活就是這么乾的。之所以被我發現,是因為在我的Android手機上,每次打開這個APP居然總能莫名其妙聽到若有若無的環境噪音樣的聲音,尤其安靜的場所下更明顯。我個人估計這個APP里用的保活音頻文件,很可能就是程序員在簡陋的條件下隨手自已錄制的,雖然也是不得以為之,但做法確實是有點粗糙。

總結一下,以上方案在當前主流手機上的運行效果

【1】雙進程守護方案(基於onStartCommand() return START_STICKY):

    1)原生5.0、5.1:原生任務欄滑動清理app,Service會被殺掉,然後被拉起,接著一直存活;

    2)金立F100(5.1):一鍵清理直接殺掉整個app,包括雙守護進程。不手動清理情況下,經測試能鎖屏存活至少40分鍾;

    3)華為暢享5x(6.0):一鍵清理直接殺掉整個app,包括雙守護進程。不手動清理下,鎖屏只存活10s。結論:雙進程守護方案失效;

    4)美圖m8s(7.1.1):一鍵清理直接殺掉整個app,包括雙守護進程。不清理情況下,鎖屏會有被殺過程(9分鍾左右被殺),之後重新復活,之後不斷被幹掉然後又重新復活。結論:雙守護進程可在後台不斷拉起Service;

    5)原生7.0:任務欄清除APP後,Service存活。使用此方案後Service照樣存活;

    6)LG V30+(7.1.2):不加雙進程守護的時候,一鍵清理無法殺掉服務。加了此方案之後也不能殺掉服務,鎖屏存活(測試觀察大於50分鍾);

    7)小米8(8.1):一鍵清理直接幹掉app並且包括雙守護進程。不清理情況下,不加守護進程方案與加守護進程方案Service會一直存活,12分鍾左右closed。結論:此方案沒有起作用。

▲ 結論:除了華為此方案無效以及未更改底層的廠商不起作用外(START_STICKY欄位就可以保持Service不被殺)。此方案可以與其他方案混合使用。

【2】監聽鎖屏廣播打開1像素Activity(基於onStartCommand() return START_STICKY):

    1)原生5.0、5.1:鎖屏後3s服務被幹掉然後重啟(START_STICKY欄位起作用);

    2)華為暢享5x(6.0):鎖屏只存活4s。結論:方案失效;

    3)美圖m8s(7.1.1):同原生5.0;

    4)原生7.0:同美圖m8s;

    5)LG V30+(7.1.2):鎖屏後情況跟不加情況一致,服務一致保持運行,結論:此方案不起作用;

    6)小米8(8.1):關屏過2s之後app全部被幹掉。結論:此方案沒有起作用。

▲ 結論:此方案無效果。

【3】故意在後台播放無聲的音樂(基於onStartCommand() return START_STICKY):

    1)原生5.0、5.1:鎖屏後3s服務被幹掉然後重啟(START_STICKY欄位起作用);

    2)華為暢享5x(6.0):一鍵清理後服務依然存活,需要單獨清理才可殺掉服務,鎖屏8分鍾後依然存活。結論:此方案適用;

    3)美圖m8s(7.1.1):同5.0;

    4)原生7.0:任務管理器中關閉APP後服務被幹掉,大概過3s會重新復活(同僅START_STICKY欄位模式)。結論:看不出此方案有沒有其作用;

    5)LG V30+(7.1.2):使用此方案前後效果一致。結論:此方案不起作用;

    6)小米8(8.1):一鍵清理可以殺掉服務。鎖屏後保活超過20分鍾。

▲ 結論:成功對華為手機保活。小米8下也成功突破20分鍾。

【4】使用JobScheler喚醒Service(基於onStartCommand() return START_STICKY):

    1)原生5.0、5.1:任務管理器中幹掉APP,服務會在周期時間後重新啟動。結論:此方案起作用;

    2)華為暢享5x(6.0):一鍵清理直接殺掉APP,過12s左右會自動重啟服務,JobScheler起作用;

    3)美圖m8s(7.1.1):一鍵清理直接殺掉APP,無法自動重啟;

    4)原生7.0:同美圖m8s(7.1.1);

    5)小米8(8.1):同美圖m8s(7.1.1)。

▲ 結論:只對5.0,5.1、6.0起作用。

【5】混合使用的效果,並且在通知欄彈出通知:

    1)原生5.0、5.1:任務管理器中幹掉APP,服務會在周期時間後重新啟動。鎖屏超過11分鍾存活;

    2)華為暢享5x(6.0):一鍵清理後服務依然存活,需要單獨清理才可殺掉服務。結論:方案適用;

    3)美圖m8s(7.1.1):一鍵清理APP會被殺掉。正常情況下鎖屏後服務依然存活;

    4)原生7.0:任務管理器中關閉APP後服務被幹掉,過2s會重新復活;

    5)小米8(8.1):一鍵清理可以殺掉服務,鎖屏下後台保活時間超過38分鍾;

    6)榮耀10(8.0):一鍵清理殺掉服務,鎖屏下後台保活時間超過23分鍾。

❷ Android中的保活機制

Android中的保活是一個永不過時的話題,因為每一個APP都希望能在後台不停的運行去搜集用戶數據,在Android 系統處於較低版本的時候(目前最新版本為12,較低版本指的是8以下),很多APP藉助於系統層面的漏洞研發出了各種保活的方法,但是隨著Android 版本的不斷更新,過往的保活方法漸漸失效,Android中的保活成為了一個越來越難辦到的事情,但是我認為這是一個好事,如非這樣你永遠不知道你的手機後台到底有多少APP背著你幹了多少事情。當然,系統的事情不是我們能掌控的了的。那麼,我們先來看看以前為了保活都有哪些手段。

手段一:在Service的onStartCommand方法中返回****START_STICKY****(****親測無效****)

在Service的onStartCommand方法中返回鍵有下面幾種可供選擇:

(1)START_STICKY:如果Service所在的進程,在執行了onStartCommand方法後,被清理了,那麼這個Service會被保留在已開始的狀態,但是不保留傳入的Intent,隨後系統會嘗試重新創建此Service。

(2)START_NOT_STICKY:如果Service所在的進程,在執行了onStartCommand方法後,被清理了,則系統不會重新啟動此Service。

(3)START_REDELIVER_INTENT:如果Service所在的進程,在執行了onStartCommand方法後,被清理了,則結果和START_STICKY一樣,也會重新創建此Service並調用onStartCommand方法。不同之處在於,如果是返回的是START_REDELIVER_INTENT ,則重新創建Service時onStartCommand方法會傳入之前的intent。

手段二:在清單文件裡面設置優先順序****(****親測無效****)

手段三:在Service即將銷毀的時候重新啟動****(****親測無效****)

手段四:藉助AIDL使用雙進程保活****(****親測無效****)

首先創建一個AIDL文件

創建本地服務

創建遠程服務:

最後在清單文件聲明:

手段五:1像素的Activity讓應用在熄屏後保活****(****親測無效****)

具體怎麼實現可以參照這篇文章

<u>https://blog.csdn.net/zhenufo/article/details/79317068</u>

運行一段時間後系統會自動殺死整個APP

手段六:****開啟前台服務(親測有效)

在Service的onCreate方法中開啟前台服務

當然,APP保活的方式方法遠不止這些,但是隨著Android 系統的不斷優化,保活現在越來越不太現實,但是我們可以盡量提高我們APP的優先順序讓系統不輕易殺死我們的APP,這一點還是可以辦到的。

❸ Android跨進程通信

本文整理和引用他人的筆記,旨在個人復習使用。

參考鏈接:

https://blog.csdn.net/fanleiym/article/details/83894399

https://github.com/274942954/AndroidCollection/blob/master/Docs/Android%E7%9F%A5%E8%AF%86%E7%82%B9%E6%B1%87%E6%80%BB.md#%E8%BF%9B%E7%A8%8B%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F

https://www.kaelli.com/4.html

https://carsonho.blog.csdn.net/article/details/73560642?utm_medium=distribute.pc_relevant.none-task-blog--1.e_weight&depth_1-utm_source=distribute.pc_relevant.none-task-blog--1.e_weight

默認情況下,一個app只會運行在一個進程中,進程名為app的包名。

1. 分散內存的佔用

Android系統對每個應用進程的內存佔用是有限制的,佔用內存越大的進程,被系統殺死的可能性就越大。使用多進程可以減少主進程佔用的內存,避免OOM問題,降低被系統殺死的概率。

2. 實現多模塊

一個成熟的應用一定是多模塊化的。項目解耦,模塊化,意味著開辟新的進程,有獨立的JVM,帶來數據解耦。模塊之間互不幹預,團隊並行開發,同時責任分工也很明確。

3. 降低程序奔潰率

子進程崩潰不會影響主進程的運行,能降低程序的崩潰率。

4. 實現一些特殊功能

比如可以實現推送進程,使得主進程退出後,能離線完成消息推送服務。還可以實現守護進程,來喚醒主進程達到保活目的。還可以實現監控進程專門負責上報bug,進而提升用戶體驗。

android:process 屬性的值以冒號開頭的就是 私有進程 ,否則就是 公有進程 。當然命名還需要符合規范,不能以數字開頭等等。

1. 前台進程

2. 可見進程

3. 服務進程

4. 後台進程

5. 空進程

Android 會將進程評定為它可能達到的最高級別。另外服務於另一進程的進程其級別永遠不會低於其所服務的進程。

創建新的進程時會創建新的Application對象,而我們通常在Application的onCreate方法中只是完成一些全局的初始化操作,不需要多次執行。

解決思路:獲取當前進程名,判斷是否為主進程,只有主進程的時候才執行初始化操作

獲取當前進程名的兩種方法:

Application中判斷是否是主進程(方法1例子):

Serializable 和 Parcelable是數據序列化的兩種方式,Android中只有進行序列化過後的對象才能通過intent和Binder傳遞。

通常序列化後的對象完成傳輸後,通過反序列化獲得的是一個新對象,而不是原來的對象。

Serializable是java介面,位於java.io的路徑下。Serializable的原理就是把Java對象序列化為二進制文件後進行傳遞。Serializable使用起來非常簡單,只需直接實現該介面就可以了。

Parcelable是Google為了解決Serializable效率低下的問題,為Android特意設計的一個介面。Parcelable的原理是將一個對象完全分解,分解成可以傳輸的數據類型(如基本數據類型)再進行傳遞。

通常需要存到本地磁碟的數據就使用Serializable,其他情況就使用效率更高的Parcelable。

IPC 即 Inter-Process Communication (進程間通信)。Android 基於 Linux,而 Linux 出於安全考慮,不同進程間不能之間操作對方的數據,這叫做「進程隔離」。

每個進程的虛擬內存空間(進程空間)又被分為了 用戶空間和內核空間 進程只能訪問自身用戶空間,只有操作系統能訪問內核空間。

由於進程只能訪問自身用戶空間,因此在傳統的IPC中,發送進程需要通過_from_user(系統調用)將數據從自身用戶空間拷貝到內核空間,再由接受進程通過_to_user從內核空間復拷貝到自身用戶空間,共需要拷貝2次,效率十分低下。Android採用的是Binder作為IPC的機制,只需復制一次。

Binder翻譯過來是粘合劑,是進程之間的粘合劑。

Binder IPC通信的底層原理是 通過內存映射(mmap),將接收進程的用戶空間映射到內核空間 ,有了這個映射關系,接收進程就能通過用戶空間的地址獲得內核空間的數據,這樣只需發送進程將數據拷貝到內核空間就可完成通訊。

一次完整的Binder IPC通信:

從IPC的角度看,Binder是一種跨進程通信機制(一種模型),Binder 是基於 C/S 架構的,這個通信機制中主要涉及四個角色:Client、Server、ServiceManager和Binder驅動。

Client、Server、ServiceManager都是運行在用戶空間的進程,他們通過系統調用(open、mmap 和 ioctl)來訪問設備文件/dev/binder,從而實現與Binder驅動的交互。Binder驅動提供進程間通信的能力(負責完成一些底層操作,比如開辟數據接受緩存區等),是Client、Server和ServiceManager之間的橋梁。

Client、Server就是需要進行通信兩個的進程,通信流程:

細心的你一定發現了,注冊服務和獲得服務本身就是和ServiceManager進行跨進程通信。其實和ServiceManager的通信的過程也是獲取Binder對象(早已創建在Binder驅動中,攜帶了注冊和查詢服務等介面方法)來使用,所有需要和ServiceManager通信的進程,只需通過0號引用,就可以獲得這個Binder對象了。

AIDL內部原理就是基於Binder的,可以藉此來分析Binder的使用。

AIDL是介面定義語言,簡短的幾句話就能定義好一個復雜的、內部有一定功能的java介面。

先看看ICallBack.aidl文件,這里定義了一個介面,表示了服務端提供的功能。

被定義出來的java介面繼承了IInterface介面,並且內部提供了一個Stub抽象類給服務端(相當於封裝了一下,服務端只需繼承這個類,然後完成功能的裡面具體的實現)。

參考: https://www.cnblogs.com/sqchen/p/10660939.html

(以下是添加了回調的最終實現,可以看參考鏈接一步一步來)

為需要使用的類,創建aidl文件。

系統會自動在main文件下生成aidl文件夾,並在該文件夾下創建相應目錄。

在java相同路徑下創建Student類,這里不能使用@Parcelize註解,否則會報錯

創建IStudentService.aidl,定義了一個介面,該介面定義了服務端提供的功能。創建完後rebuild一下項目 (每次創建和修改定義介面文件都要rebuild一下)

創建在服務端的StudentService

可以看見有回調,說明客戶端也提供了介面給服務端來回調(雙向通信,此時客戶端的變成了服務端),即ICallBack.aidl

客戶端是通過Binder驅動返回的Binder調用StudentService里的具體實現方法

AIDL使用注意:

Messenger可以在不同進程中傳遞 Message 對象,在Message中放入我們需要傳遞的數據,就可以輕松地實現數據的進程間傳遞了。Messenger 是一種輕量級的 IPC 方案,是對AIDL的封裝,底層實現是 AIDL。

使用詳見: https://blog.csdn.net/qq951127336/article/details/90678698

❹ Android 7.0 和8.0 如何保活

1.控制onStartCommand函數的返回值。

我對這個函數的理解是:當服務被異常終止時,是否重啟服務?

有些文章裡面在用這個做保活時,修改的是flag,在我實際測試中是無效。有效的做法是直接返回參數。另外默認的flags值為0,是START_STICKY_COMPATIBILITY。如下:

[java]view plain

❺ 進程保活

一 、問:什麼是進程保活?

答:進程保活就是進程永遠存在內存中,是殺不死的,就算殺死了也會有辦法重新啟動起來,其實這些並不是流氓手段,很多情況下,如果你想給你的用戶提供服務,就必須有一個進程常駐著,便於在特定的時候做一些特定的事情,比如廣播接受者,他就不支持靜態注冊,也就是說如果我們想接受屏幕開關啟動的廣播,必須要在進程中動態注冊,這個時候如果沒有一個常駐的進程,鎖屏業務就無法正常的為用戶展開服務。

二、問:進程是怎麼死掉的呢?

答:其實進程被殺死的原因,一方面是人為的,二、可能被第三方應用殺死,如殺敵軟體等。

三、問:Android進程的優先順序?

答:

  1、前台進程 (Foreground process):用戶當前操作所在的進程,當內存不足以承擔前台進程的使用,才有可能回收

  2、可見進程(Visible process):沒有任何前台組件,但是仍然會影響屏幕上所見內容,他是一種極為重要的進程,除非為了維持前台進程,因內存不足,有可能會回收掉可見進程,否則系統是不會回收可見進程。

  3、服務進程(Service process):他與用戶所見的內容是沒有直接關聯,但是他們通常執行一些用戶關心的操作,比如說在後台獲取網路數據,後台播放音樂,後台進行一些數據計算等。被殺死的原因:也是為了

  支持前台進程和可見進程,因內存不足情況下才會被回收。

  4、後台進程(BaclGround process):對用戶的體驗沒有直接的影響,用戶可以隨時終止他們,這個進程是為了供給上面三個進程來使用的,通常在後台進程運行著很多操作,他們保存在一個列表當中,為了確保用戶最近查看Activit的進程最後一個被終止,他是一個LRU演算法

  5、空進程(Empty process) :保存這個進程的唯一目的就是用來做緩存,以縮短下次在運行組件所需的啟動時間,為了使系統總體的資源在進程緩存和內存底層之間保持平衡。它是不包括任何組件的進程.

四、問:Android進程的回收策略?

答:Android進程的回收策略主要是通過Low memory killer機制來完成的。

  Low memory killer:通過一些比較復雜的評分機制,對進程進行打分,然後講分數的進程判定為bad進程,殺死並釋放內存。Low memory killer是定時進行檢查的,它主要是通過進程的OOM_ODJ來判斷進程的優先順序。當OOM_ODJ的值越小,進程的優先順序越高,而OOM_ODJ越不會去回收。反之就會被回收。

  注意:Low memory killer和out memory不一樣的地方:out memory機制只有當系統內存不足的時候才會啟動檢查,而Low memory killer是定時進行檢查的,它主要是通過進程的OOM_ODJ來判斷進程的優先順序。

五、問:進程保活方案?

答:Android進程的回收策略主要是通過Low memory killer機制來完成的。

  1、利用系統廣播拉活,在發生系統事件的時候,系統會發出相應的廣播,

    詳情查看:http://blog.csdn.NET/sunshinetan/article/details/53126857

  2、利用系統Service機制拉活,在Service有一個onStartCommand

    推薦博客:http://blog.csdn.net/wulianghuan/article/details/8596467

    Android開發的過程中,每次調用startService(Intent)的時候,都會調用該Service對象的onStartCommand(Intent,int,int)方法,然後在onStartCommand方法中做一些處理。然後我們注意到這個函數有一個int的返回值,這篇文章就是簡單地講講int返回值的作用。從Android官方文檔中,我們知道onStartCommand有4種返回值:

    START_STICKY:如果service進程被kill掉,保留service的狀態為開始狀態,但不保留遞送的intent對象。隨後系統會嘗試重新創建service,由於服務狀態為開始狀態,所以創建服務後一定會調用onStartCommand

    (Intent,int,int)方法。如果在此期間沒有任何啟動命令被傳遞到service,那麼參數Intent將為null。(service因內存不足的情況下,殺死的進程才可以拉活,這里要特別注意,不是所有情況都可以拉活。第一次server被殺死後,會在5秒後拉活,第二次會在10秒後,第三次會在20秒後。之後就不會在拉活。第二種情況是獲得root許可權通過stop停止的,也是無法通過server拉活)

    START_NOT_STICKY:「非粘性的」。使用這個返回值時,如果在執行完onStartCommand後,服務被異常kill掉,系統將會把它置為started狀態,系統不會自動重啟該服務,直到startService(Intent intent)方法再次被用;。

    START_REDELIVER_INTENT:重傳Intent。使用這個返回值時,如果在執行完onStartCommand後,服務被異常kill掉,系統會自動重啟該服務,並將Intent的值傳入。

    START_STICKY_COMPATIBILITY:START_STICKY的兼容版本,但不保證服務被kill後一定能重啟。

  3、利用Native進程拉活,

  4、利用JobScheler機制拉活:Android5.0之後提供的一個機制,他會監聽主進程的存活,如果死掉就會激活拉活進程。

  5、利用賬號同步機制拉活:android系統有一個賬戶系統,設置一個自己的賬戶,android會定期喚醒賬戶更新服務。我們可以自己設定同步的事件間隔,且發起更新的是系統,不會受到任何限制。需要在 AndroidManifest 中定義賬號授權與同步服務。

    Android 版本(Android N)中系統對賬戶同步這里做了變動,該方法不再有效。

    缺點:

          a.用戶會在系統設置的賬戶列表裡面看到一個不認識的賬戶;

          b.同步的事件間隔是有限制的,最短1分鍾,見源碼,如果小雨60秒,置為60秒;

          c.用戶可以卸載賬戶;

          d.必須聯網!google提供這個組件是讓你同步賬戶信息,不聯網就不能保活!

❻ Android-保活

Low Memory Killer

打開的應用越多,後台緩存的進程也越多。因為系統出於體驗和性能上的考慮,app在退到後台時系統並不會真正的kill掉這個進程,而是將其緩存起來。於是在系統內存不足的情況下,系統開始依據自身的一套進程回收機制來判斷要kill掉哪些進程,以騰出內存來供給需要的app, 這套殺進程回收內存的機制就叫 Low Memory Killer。

進程的優先順序(by:https://developer.android.google.cn/guide/components/activities/process-lifecycle?hl=zh-cn)

前台進程

用戶正在使用的程序,一般系統是不會殺死前台進程的,除非用戶強制停止應用或者系統內存不足等極端情況會殺死。

可見進程

用戶正在使用,看得到,但是摸不著,沒有覆蓋到整個屏幕,只有屏幕的一部分可見進程不包含任何前台組件,一般系統也是不會殺死可見進程的,除非要在資源吃緊的情況下,要保持某個或多個前台進程存活施。

服務進程

在內存不足以維持所有前台進程和可見進程同時運行的情況下,服務進程會被殺死。

後台進程

系統可能隨時終止它們,回收內存。

空進程

某個進程不包含任何活躍的組件時該進程就會被置為空進程,完全沒用,殺了它只有好處沒壞處,第一個干它。

內存閾值

內存閾值在不同的手機上不一樣,一旦低於該值,Android便會殺死對應優先順序的進程。一旦低於該值,Android便開始按逆序關閉進程。即優先順序從最高的空進程開始,逆序關閉,直到內存足夠。

如何判斷進程的優先順序?

通過 oom_adj 值,判斷進程的優先順序,不同手機的oom_adj 值可能不一樣。

我們了解這個有什麼用呢?PS:了解這個你才能想辦法保證自己怎麼不被殺掉。

網上的一些方案和自己認為有用的方案

1 開啟一個像素Activity(偽前台進程)

在鎖屏的時候在本進程開啟一個Activity,為了欺騙用戶,讓這個Activity的大小是1像素,並且透明無切換動畫,在開屏幕的時候,把這個Activity關閉掉,所以這個就需要監聽系統鎖屏廣播。

我們的應用就始終和前台進程是一樣的優先順序了,為了省電,系統檢測到鎖屏事件後一段時間內會殺死後台進程,如果採取這種方案,就可以避免了這個問題,但是還是有被殺掉的可能。

Android5.0以下:

Process.killProcessQuiet(pid);

Android5.0以後:

Process.killProcessQuiet(app.pid);

Process.killProcessGroup(app.info.uid, app.pid);

應用退出後,ActivityManagerService不僅把主進程給殺死,另外把主進程所屬的進程組一並殺死,這樣一來,由於子進程和主進程在同一進程組,子進程在做的事情,也就停止了。

2 相互喚醒(廣播喚醒)

相互喚醒的意思就是,假如你手機里裝了支付寶、淘寶、天貓、UC等阿里系的app,那麼你打開任意一個阿里系的app後,有可能就順便把其他阿里系的app給喚醒了。這個完全有可能的。此外,開機,網路切換、拍照、拍視頻時候,利用系統產生的廣播也能喚醒app,不過Android N已經將這三種廣播取消了。

3 JobSheler機制保活(不推薦)

JobSheler是作為進程死後復活的一種手段,native進程方式最大缺點是費電, Native 進程費電的原因是感知主進程是否存活有兩種實現方式,在 Native 進程中通過死循環或定時器,判斷主進程是否存活,當主進程不存活時進行拉活。其次5.0以上系統不支持。  但是JobSheler可以替代在Android5.0以上native進程方式,這種方式即使用戶強制關閉,部分廠商手機(如:華為)也能被拉起來,但AndroidN失效。

4 粘性服務&與系統服務捆綁()

這個是系統自帶的,onStartCommand方法必須具有一個整形的返回值,這個整形的返回值用來告訴系統在服務啟動完畢後。Service的onStartCommand方法里返回 STATR_STICK,onDestory中start自啟(准確的將算不上進程拉活,只能算service自啟,force_stop後不能正常拉活)。

5 監聽第三方app開放的靜態廣播(同2)

需要大量反編譯app去找開放的靜態廣播,而且不保證長期有效,可能第三方開放廣播在版本升級時改為私有廣播,如果自己公司有多個app,可廣播互相拉起。

6 NDK+Socket通過fork實現進程保活方案()

實現進程守護實際是守護app的主要服務,當app主進程被系統kill時,主要服務也會殺死,守護進程將其喚醒。

實現原理圖:

進程保活方案調研結果

未能實現真正意義上的進程保活。

光從保活這一點來說,綁定一個像素activity和循環一個無聲的聲音這種方法比較好,但是對用戶來說太流氓了,不推薦。  對於有硬性需求的,可以引導用戶加入白名單。至於推送,  可以嘗試集成多個推送方案,小米,華為等都有推送sdk,在對應手機上可以確保收到消息,  然後像網路這種是多app公用通道的,也就是手機中有一個使用網路推送的app被允許後台啟動,就能讓其他app收到推送。隨著Android版本的不斷更新及國內廠商對ROM的不斷優化,如何最大可能的對進程保活,是Android一道需要長期學習/鑽研的學問,也是Android開發者不得不面對的問題。

引援:https://www.jianshu.com/p/1c353edf73ba

❼ Android 守護進程的實現方式

在我們進行應用開發時,會遇到上級的各種需求,其中有一條 剛需: 後台保活 ,更有甚者:

我要我們的應用永遠活在用戶的手機後台不被殺死 —— 這都 TM 的扯淡

除了系統級別的應用能持續運行,所有三方程序都有被殺死的那一天!當然 QQ/微信/陌陌 等會好一些,因為他們已經深入設備的 心 ;
我們能做的只是通過各種手段盡量讓我們的程序在後台運行的時間長一些,或者在被幹掉的時候,能夠重新站起來,而且這個也不是每次都有效的,也是不能在所有的設備的上都有效的;要做到後台進程保活,我們需要做到兩方便:

要實現實現上邊所說,通過下邊幾點來實現,首先我們需要了解下進程的優先順序劃分:

Process Importance 記錄在 ActivityManager.java 類中:

了解進程優先順序之後,我們還需要知道一個進程回收機制的東西;這里參考 AngelDevil 在博客園上的一篇文章:

Android 的 Low Memory Killer 基於 Linux 的 OOM 機制,在 Linux 中,內存是以頁面為單位分配的,當申請頁面分配時如果內存不足會通過以下流程選擇bad進程來殺掉從而釋放內存:

在 Low Memory Killer 中通過進程的 oom_adj 與佔用內存的大小決定要殺死的進程, oom_adj 越小越不容易被殺死;
Low Memory Killer Driver 在用戶空間指定了一組內存臨界值及與之一一對應的一組 oom_adj 值,當系統剩餘內存位於內存臨界值中的一個范圍內時,如果一個進程的 oom_adj 值大於或等於這個臨界值對應的 oom_adj 值就會被殺掉。

下邊是表示 Process State (即老版本里的 OOM_ADJ )數值對照表,數值越大,重要性越低,在新版SDK中已經在 android 層去除了小於0的進程狀態

Process State (即老版本的 OOM_ADJ )與 Process Importance 對應關系,這個方法也是在 ActivityManager.java 類中,有了這個關系,就知道可以知道我們的應用處於哪個級別,對於我們後邊優化有個很好地參考

一般情況下,設備端進程被幹掉有一下幾種情況

由以上分析,我們可以可以總結出,如果想提高我們應用後台運行時間,就需要提高當前應用進程優先順序,來減少被殺死的概率

分析了那麼多,現在對Android自身後台進程管理,以及進程的回收也有了一個大致的了解,後邊我們要做的就是想盡一切辦法去提高應用進程優先順序,降低進程被殺的概率;或者是在被殺死後能夠重新啟動後台守護進程

第一種方式就是利用系統漏洞,使用 startForeground() 將當前進程偽裝成前台進程,將進程優先順序提高到最高(這里所說的最高是服務所能達到的最高,即1);

這種方式在 7.x 之前都是很好用的,QQ、微信、IReader、Keep 等好多應用都是用的這種方式實現;因為在7.x 以後的設備上,這種偽裝前台進程的方式也會顯示出來通知欄提醒,這個是取消不掉的,雖然 Google 現在還沒有對這種方式加以限制,不過這個已經能夠被用戶感知到了,這種方式估計也用不了多久了

下邊看下實現方式,這邊這個 VMDaemonService 就是一個守護進程服務,其中在服務的 onStartCommand() 方法中調用 startForeground() 將服務進程設置為前台進程,當運行在 API18 以下的設備是可以直接設置,API18 以上需要實現一個內部的 Service ,這個內部類實現和外部類同樣的操作,然後結束自己;當這個服務啟動後就會創建一個定時器去發送廣播,當我們的核心服務被幹掉後,就由另外的廣播接收器去接收我們守護進程發出的廣播,然後喚醒我們的核心服務;

當我們啟動這個守護進程的時候,就可以使用以下 adb 命令查看當前程序的進程情況(需要 adb shell 進去設備),
為了等下區分進程優先順序,我啟動了一個普通的後台進程,兩外兩個一個是我們啟動的守護進程,一個是當前程序的核心進程,可以看到除了後台進程外,另外兩個進程都帶有 isForeground=true 的屬性:

然後我們可以用下邊的命令查看 ProcessID

有了 ProcessID 之後,我們可以根據這個 ProcessID 獲取到當前進程的優先順序狀態 Process State ,對應 Linux 層的 oom_adj
可以看到當前核心進程的級別為 0 ,因為這個表示當前程序運行在前台 UI 界面,守護進程級別為 1 ,因為我們利用漏洞設置成了前台進程,雖然不可見,但是他的級別也是比較高的,僅次於前台 UI 進程,然後普通後台進程級別為 4 ;當我們退到後台時,可以看到核心進程的級別變為 1 了,這就是因為我們利用 startForeground() 將進程設置成前台進程的原因,這樣就降低了進程被系統回收的概率了;

可以看到這種方式確實能夠提高進程優先順序,但是在一些國產的設備上還是會被殺死的,比我我測試的時候小米點擊清空最近運行的應用進程就別幹掉了;當把應用加入到設備白名單里就不會被殺死了,微信就是這樣,人家直接裝上之後就已經在白名單里了,我們要做的就是在用戶使用中引導他們將我們的程序設置進白名單,將守護進程和白名單結合起來,這樣才能保證我們的應用持續或者

Android系統在5.x以上版本提供了一個 JobSchele 介面,系統會根據自己實現定時去調用改介面傳遞的進程去實現一些操作,而且這個介面在被強制停止後依然能夠正常的啟動;不過在一些國產設備上可能無效,比如小米;
下邊是 JobServcie 的實現:

我們要做的就是在需要的時候調用 JobSchele 的 schele 來啟動任務;剩下的就不需要關心了, JobSchele 會幫我們做好,下邊就是我這邊實現的啟動任務的方法:

在實現 Service 類時,將 onStartCommand() 返回值設置為 START_STICKY ,利用系統機制在 Service 掛掉後自動拉活;不過這種方式只適合比較原生一些的系統,像小米,華為等這些定製化比較高的第三方廠商,他們都已經把這些給限制掉了;

這種方式在以下兩種情況無效:

事事沒有絕對,萬物總有一些漏洞,就算上邊的那些方式不可用了,後邊肯定還會出現其他的方式;我們不能保證我們的應用不死,但我們可以提高存活率;

其實最好的方式還是把程序做好,讓程序本身深入人心,別人喜歡你了,就算你被幹掉了,他們也會主動的把你拉起來,然後把你加入他們的白名單,然後我們的目的就實現了不是 😁 ~

❽ Android保活方案

系統出於性能和體驗上的考慮,APP退到後台後並不會真正的kill、掉進程,而是將其緩存起來。
打開的應用越多,緩存的應用也就越多,在系統進程不足的情況下,系統根據自己的一套進程回收機制,來判斷kill掉哪些進程,以騰出進程給需要的app,這套進程回收機制叫做low memory killer。

內存閥值,每個手機都不一樣,當可用內存小於該值得時候,Android就會殺死對應優先順序得進程。

進程的優先順序通過oom_adj來判斷,oom_adj取值如下:

0-3是比較安全的oom_adj一般不會被系統殺死的,所以我們只要保證自己的app oom_adj在0-3之間就可以了。
可以通過adb命令:cat /proc /4181/oom_adj來查看自己app的oom_adj的值
4181是進程號

原理:手機關閉屏幕的時候,偷偷創建一個activity,讓應用成為前台進程,打開屏幕時關閉activity,這樣用戶就不會發現什麼異常,我們知道前台應用的oom_adj為0是不會被殺死的,這樣就達到看保活的目的。

缺點:activity不夠干凈,只有在息屏的時候才生效,存在局限性比較大,而且谷歌原生的系統息屏的時候不會清理進程,但是現在很多廠商會在息屏的時候清理內存,所以本方案的可行性不高,可以作為了解。

保活原理:啟動一個前台服務,從而拉高整個應用的優先順序。
因為一旦通知被用戶幹掉那麼該保活方案就不好用了,所以通知圖標存在與否是該方案是否可行的關鍵。
但是該方案是谷歌官方承認的保活方案,所以可行性還是很高的。
需要適配
API<18通知圖標不會顯示

API>=18&&API<26可以啟動雙服務,綁定同樣的D,然後stop
這個方法的原理是8.0系統之前會根據服務的id來判斷通知,那麼第二個id設置跟第一個相同,然後自殺,系統就會誤認為此通知已死就不會通知了,那麼通知欄上面就不會顯示

API>=26後暫時沒有方式能夠隱藏
8.0之後不可以創建同樣的id的通知,所以此隱藏通知的方法就不好用了,當然了,通知顯示與否不是該方案成功的評判標准,所以說還是可以用的。

在發生特定系統事件時,系統會發出廣播,通過在 Androidmanifest中靜
態注冊對應的廣播監聽器,即可在發生響應事件時拉活
但是從 android7.0開始,對廣播進行了限制,而且在8.0更加嚴格該方法就不適用了。

有多個app在用戶設備上安裝,只要開啟其中一個就可以將其他的app也拉
活。比如手機里裝了手Q、QQ空間、興趣部落等等,那麼打開任意一個app後,其
他的app也都會被喚醒

系統每隔一段時間會進行賬戶同步,當系統去賬戶同步的時候(不一定多長時間,跟系統有關),我們就去拉活app,這個方案是非常穩定的,當然了國內的系統都是定製的,所以還是需要一定的適配的。
優點:系統喚醒,比較穩定
缺點:時間不能把控

JobScheler允許在特定狀態與特定時間間隔周期執行任務。可以利
用它的這個特點完成保活的功能,效果即開啟一個定時器,與普通定時器不
同的是其調度由系統完成。
同樣在某些ROM可能並不能達到需要的效果

❾ Android後台進程保活方案

思想: 使用 Linux 中的 fork 機制創建 Native 進程,在 Native 進程中監控主進程的存活,當主進程掛掉後,在 Native 進程中立即對主進程進行拉活。

原理: 在 Android 中所有進程和系統組件的生命周期受 ActivityManagerService 的統一管理。Android5.0以下通過 Linux 的 fork 機制創建的進程為純 Linux 進程,其生命周期不受 Android 的管理。

該方案主要適用於 Android5.0 以下版本手機。

該方案不受 forceclose 影響,被強制停止的應用依然可以被拉活,在 Android5.0 以下版本拉活效果非常好。
詳情

對於 Android5.0 以上手機,系統雖然會將native進程內的所有進程都殺死,這里其實就是系統「依次」殺死進程時間與拉活邏輯執行時間賽跑的問題,如果可以跑的比系統邏輯快,依然可以有效拉起。在 某些 Android 5.0 以上機型有效。
詳情

https://github.com/Marswin/MarsDaemon

作者5.0以下系統用一個java進程和一個fork出來的純native進程雙管道互鎖監聽對方的狀態,無論哪個被殺後都拉起第三個進程,第三個進程來拉活常駐進程,實現拉活。
5.0以上同一進程組的進程會被同時殺死,所以5.0以上使用雙java進程在native層互鎖文件實現監聽,但任務管理器會在短時間內殺死所有進程,只能用反射提前初始化pacel,在進程被殺的時候和系統搶那幾十毫秒的時間發送一個拉活的廣播。用4個文件來讓兩個進程實現互鎖來做監聽,但實際效果很一般,測試了幾個5.0以上的國產機型都不行,效果是根本監聽不到進程被殺,目測原因是當任務管理器查殺進程的時候將所有的進程都掛起了,隨後全部殺掉,並在一段時間內禁止進程啟動。

PersistedJobService.java

BootReceiver.java靜態注冊BroadcastReceiver

注冊,開機,網路切換、拍照、拍視頻時候,利用系統產生的廣播也能喚醒app,不過Android N已經將這三種廣播取消了

常用的拉活許可權

BackgroundService.java
WakeLock

作為前台應用運行,提高應用存活幾率

service被關掉後自動啟動

START_STICKY
如果系統在onStartCommand返回後被銷毀,系統將會重新創建服務並依次調用onCreate和onStartCommand(注意:根據測試Android2.3.3以下版本只會調用onCreate根本不會調用onStartCommand,Android4.0可以辦到),這種相當於服務又重新啟動恢復到之前的狀態了)。

START_NOT_STICKY
如果系統在onStartCommand返回後被銷毀,如果返回該值,則在執行完onStartCommand方法後如果Service被殺掉系統將不會重啟該服務。

START_REDELIVER_INTENT
START_STICKY的兼容版本,不同的是其不保證服務被殺後一定能重啟。

service注冊,許可權設置為高優先順序

KeepAliveService.java
注冊,在新的獨立進程內啟動,適用5.0以下的原生系統,5.0以上同樣會被殺死

他的局限性在於:
第一,用戶會在系統設置的賬戶列表裡面看到一個不認識的賬戶;
第二,同步的事件間隔是有限制的,最短1分鍾,見源碼,如果小雨60秒,置為60秒。而且各種國產機怎麼改的源碼我們未可知,是不是都能用仍然未可知;
第三,很致命,某些手機比如note3需要手動設置賬戶,你如何騙你的用戶給你手動設置賬戶完了之後不卸載你;
第四,也很致命,必須聯網!google提供這個組件是讓你同步賬戶信息,不聯網你同步個鬼,我們要保活,可以不聯網不做事,但是不能不聯網就死

集成三方推送平台sdk,友盟極光等

❿ android怎麼保證進程不被殺死

root吧!把進程加入系統清理白名單就行

閱讀全文

與android進程保活相關的資料

熱點內容
rf3148編程器 瀏覽:505
浙江標准網路伺服器機櫃雲主機 瀏覽:587
設置網路的伺服器地址 瀏覽:600
java圖形界面設計 瀏覽:751
純前端項目怎麼部署到伺服器 瀏覽:538
瓜子臉程序員 瀏覽:505
如何保證伺服器優質 瀏覽:94
小微信aPP怎麼一下找不到了 瀏覽:299
演算法纂要學術價值 瀏覽:975
程序員你好是什麼意思 瀏覽:801
倩女幽魂老伺服器如何玩 瀏覽:561
電子鍾單片機課程設計實驗報告 瀏覽:999
看加密頻道 瀏覽:381
程序員算不算流水線工人 瀏覽:632
三星電視我的app怎麼卸載 瀏覽:44
簡述vi編譯器的基本操作 瀏覽:507
讓程序員選小號 瀏覽:91
加強數字貨幣國際信息編譯能力 瀏覽:584
購買的app會員怎麼退安卓手機 瀏覽:891
程序員的種類及名稱 瀏覽:295