Android防止Service被殺死
阿新 • • 發佈:2018-12-01
1. Service
被殺死的兩種場景
1.2 系統回收
在系統記憶體空間不足時可能會被系統殺死以回收記憶體,記憶體不足時Android會依據Service
的優先順序來清除Service
。
1.2 使用者清除
使用者可以在”最近開啟”(多工視窗、任務管理視窗)中清除最近開啟的任務,當用戶清除了Service
所在的任務時,Service
可能被殺死(不同ROM有不同表現,在小米、魅族等第三方產商定製ROM上一般會被立即殺死,在Android N上沒有被立即殺死)。
2. 解決方案
對於第一種場景(系統回收),如果不用黑科技(雙程序互開等),我們只能夠儘量提高Service
對於第二種場景(使用者手動清除),可以將啟動Service的任務排除出系統的最近任務列表。
2.1 前臺Service
前臺Service是一種有前臺介面(Notification)、優先順序非常高的Service,只有在系統記憶體空間嚴重不足時,才會清除前臺Service。
只需要在Service的onCreate()
或者 onStartCommand()
內呼叫startForeground
,就能將Service轉為前臺Service。示例如下:
private Notification buildForegroundNotification() {
Notification.Builder builder = new Notification.Builder(this);
builder.setOngoing(true);
builder.setContentTitle(getString(R.string.notification_title))
.setContentText(getString(R.string.notification_content))
.setSmallIcon(R.mipmap.ic_launcher)
.setTicker(getString(R.string.notification _ticker));
builder.setPriority(Notification.PRIORITY_MAX);
return builder.build();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.e(TAG, "onStartCommand");
WindowManager windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
mRootView = new FloatRootView(this);
mRootView.attach(windowManager);
mRootView.showBubble();
startForeground(1, buildForegroundNotification());
return START_STICKY;
}
2.2 移出最近任務
為了使Service
不會被使用者從”最近開啟”中清除,我們可以將啟動Service
的任務從系統的最近應用列表中刪除。做法是將任務Activity
的excludeFromRecents
設為true
,如下:
<activity android:name=".MainActivity"
android:excludeFromRecents="true">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>