轉載請註明出處
http://blog.csdn.net/brucehurrican/article/details/51753334
相信好多開發的朋友都遇到過這樣的需求:app即使被用戶kill掉,關鍵服務仍要存活,即app要有一個保活的進程來保障app一直存活於後臺不被kill掉。網上關於進程保活的文章有很多,我這裏用的方法也是在網上找的。說下我遇到的需求吧:
- 服務所在保活進程一直運行在後臺,並定時處理相應業務邏輯
- 當主進程被用戶kill掉,保活進程存活
我用的方法如下:
KeepLiveService.java
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (Build.VERSION.SDK_INT < 18) {
// API < 18 ,此方法能有效隱藏Notification上的圖標
startForeground(1001, new Notification());
} else {
Intent innerIntent = new Intent(this, KeepLiveInnerService.class);
startService(innerIntent);
startForeground(1001, new Notification());
}
LogDetails.getLogConfig().configShowBorders(true);
LogDetails.i("保活服務開啓-所在進程-" + android.os.Process.myPid());
bindService(new Intent(this, KeepLiveService.class), new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
// 待處理業務邏輯
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
},BIND_AUTO_CREATE);
return super.onStartCommand(intent, flags, startId);
}
/**
* 給 API >= 18 的平臺上用的灰色保活手段
*/
private static class KeepLiveInnerService extends Service {
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
startForeground(1001, new Notification());
stopForeground(true);
stopSelf();
return super.onStartCommand(intent, flags, startId);
}
@Override
public IBinder onBind(Intent intent){
return null;
}
}
<service android:name=".keeplive.KeepLiveService" android:process=":keeplive"/>
這種保活方式也是大家用的比較多的一種,我在項目中也是用此種方法,坑點是業務需要在service start後要bind上該服務並在service connected中進行處理。因爲業務需求中有網絡請求,IO操作等一些耗時的操作。這樣導致用戶在kill app後連帶保活進程也被kill掉。根本原因是上述代碼中的bindservice,所需綁定的context被kill掉導致該保活進程服務也被kill。
我的解決方法如下:
KeepLiveBindService.java
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (Build.VERSION.SDK_INT < 18) {
// API < 18 ,此方法能有效隱藏Notification上的圖標
startForeground(1001, new Notification());
} else {
Intent innerIntent = new Intent(this, KeepLiveInnerService.class);
startService(innerIntent);
startForeground(1001, new Notification());
}
LogDetails.getLogConfig().configShowBorders(true);
LogDetails.i("保活服務開啓-所在進程-" + android.os.Process.myPid());
new Timer().scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
startService(new Intent(KeepLiveBindService.this, KeepLiveService.class));
}
},2000,3000);
return super.onStartCommand(intent, flags, startId);
}
<service android:name=".keeplive.KeepLiveBindService" android:process=":keeplive2"/>
// 此處進程可與KeepLiveService一致,爲了提高保活率我在工程使用不同的進程
新建另一個保活進程的服務在該服務中輪詢業務進程服務KeepLiveService 這樣可以達到業務需要,後臺保活。
注意:
對於原生android系統,這種保活方式是有效果的。因android 碎片化和國內各種rom 對於第三方服務的控制是不一樣的,我在做項目過程中,華爲榮耀部分機型就可以保活成功,P系列就不行。小米全系列和MX系列都是不起作用的。
全部代碼可以從我的github上下載。
如果您有更好的解決方法歡迎不吝賜教。