1. 程式人生 > >Android防止Service被殺死

Android防止Service被殺死

1. Service被殺死的兩種場景

1.2 系統回收

在系統記憶體空間不足時可能會被系統殺死以回收記憶體,記憶體不足時Android會依據Service的優先順序來清除Service

1.2 使用者清除

使用者可以在”最近開啟”(多工視窗、任務管理視窗)中清除最近開啟的任務,當用戶清除了Service所在的任務時,Service可能被殺死(不同ROM有不同表現,在小米、魅族等第三方產商定製ROM上一般會被立即殺死,在Android N上沒有被立即殺死)。

2. 解決方案

對於第一種場景(系統回收),如果不用黑科技(雙程序互開等),我們只能夠儘量提高Service

的優先順序,一種比較好的方式是使用前臺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的任務從系統的最近應用列表中刪除。做法是將任務ActivityexcludeFromRecents設為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>