㈠ 如何讓一個應用程序一直在後台運行
1、保活手段
1 業界保活手段:黑色保活,灰色保活,白色保活
2 黑色保活:
1 不同的APP進程,用廣播相互喚醒,包括利用系統廣播進行喚醒
2 常見手段:
1 開機,網路切換,拍照,拍視頻等利用系統廣播喚醒APP
此場景Google已經意識到,在android N 取消了 拍照,視頻,網路切換的廣播
2 接入第三方的SDK也會喚醒相應的APP進程
3 假如你手機里裝了支付寶,淘寶,UC等阿里系的APP,那麼你打開任何一個,都有可能喚醒其他的阿里系的APP
3 白色保活:
就是調用系統的API啟動一個前台Service進程,這樣會在通知欄生成一個Notification,用戶知道哪些進程正在運行
4 灰色保活
1 保活領域應用最為廣泛,利用系統的漏洞來啟動一個前台的Service進程,與「白色保活」不同的是,它不會在通知欄生成一個Notification,用戶無法察覺,但是優先順序要高於普通的後台進程。
2 實現思路
思路一:當API<18,啟動前台的Service直接傳入new Notification();
思路二:當API >= 18,同時啟動兩個id相同的前台Service,然後再將後啟動的Service做stop處理
代碼這樣寫:
[java]view plain
importandroid.app.Notification;
importandroid.app.Service;
importandroid.content.Intent;
importandroid.os.Build;
importandroid.os.IBinder;
/**
*APP灰色保活
*Createdbyfflinon2016/4/23.
*/
{
privatefinalstaticintGRAY_SERVICE_ID=1001;
@Override
publicIBinderonBind(Intentintent){
returnnull;
}
@Override
publicintonStartCommand(Intentintent,intflags,intstartId){
//API<18,此方法能有效地隱藏notification的圖標
if(Build.VERSION.SDK_INT<18){
startForeground(GRAY_SERVICE_ID,newNotification());
}else{
Intentintent1=newIntent(this,GrayInnerService.class);
startService(intent1);
startForeground(GRAY_SERVICE_ID,newNotification());
}
returnsuper.onStartCommand(intent,flags,startId);
}
//給API>=18的平台上做灰色保護手段
{
@Override
publicIBinderonBind(Intentintent){
returnnull;
}
@Override
publicintonStartCommand(Intentintent,intflags,intstartId){
startForeground(GRAY_SERVICE_ID,newNotification());
stopForeground(true);
stopSelf();
returnsuper.onStartCommand(intent,flags,startId);
}
}
}
3 檢驗方法:
首先看系統通知欄有沒有Notification,如果沒有,就進入手機adb shell模式,輸入命令mpsys activity services PackageName
列印出指定包名的所有進程中的service信息,看下有沒有isForground=true的信息,如果有,就說明了該APP使用了灰色保活
4 使用灰色保活手段並不意味著你的應用就能永生不死,只能說提高了進程的優先順序,如果應用佔用了很大的內存,還是會被回收的
2、進一步理解保活
1 進程回收機制
系統出於體驗和性能上的考慮,APP在退出後台時系統並不會真正的kill掉這個進程,而是將其緩存起來,打開的應用越多,後台緩存的進程也就越多。在系統內存不足的情況下,系統開始根據自身的一套進程回收機制來判斷要回收掉哪些進程,這套殺死進程回收內存的機制叫 Low Memory Killer,它是基於Linux內核的OOM killer機制誕生的,該機制為每個系統分配了一個值,叫做oom_adj,代表了進程的優先順序,oom_adj越大,代表優先順序越低,越容易被回收,普通APP進程的oom_adj >=0,系統的可能會小於0.
2 查看oom_adj的值,需要用到兩個shell命令
ps | grep 包名
$cat /proc/進程id/oom_adj
3 結果發現,APP推到後台,UI進程的值降低最為明顯,因為它佔用的內存資源最多,因此,為了避免後台UI進程被殺,需要盡可能的釋放一些不用的圖片,音頻資源