Service is killed after a short period of time (1

2019-04-16 17:39发布

问题:

I've created a service that its job is to clear the notifications when the app is closed by the user. Everything works perfectly well but sometimes when the application is in the background for more than 1 minute the service is killed (which means that the notifications are not cancelled). Why is this happening? I thought that the only way that you can stop a service is by using either stopSelf() or stopService().

public class OnClearFromRecentService extends Service {
    private static final String TAG = "onClearFromRecentServic";
    private NotificationManagerCompat mNotificationManagerCompat;

    @Override
    public void onCreate() {
        super.onCreate();
        mNotificationManagerCompat = NotificationManagerCompat.from(getApplicationContext());
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d(TAG, "Service Started");
        return START_NOT_STICKY;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "Service Destroyed");
    }

    @Override
    public void onTaskRemoved(Intent rootIntent) {
        //Put code here which will be executed when app is closed from user.
        Log.d(TAG, "onTaskRemoved was executed ");
        if (mNotificationManagerCompat != null) {
            mNotificationManagerCompat.cancelAll();
        } else {
            Log.d(TAG, "onTaskRemoved: mNotifManager is null!");
        }

        stopSelf();
    }
}

I start the service from the splash screen Activity like this: startService(new Intent(this, OnClearFromRecentService.class));

Also here are some Log messages:

回答1:

Try returning START_STICKY form onStartCommand.
Then system will try to recreate.
check this official doc.

@Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d(TAG, "Service Started");
        return START_NOT_STICKY;
    }

Also you can try returing START_REDELIVER_INTENT,if you also want Intent to be re-delivered.

START_REDELIVER_INTENT

Constant to return from onStartCommand(Intent, int, int): if this service's process is killed while it is started (after returning from onStartCommand(Intent, int, int)), then it will be scheduled for a restart and the last delivered Intent re-delivered to it again via onStartCommand(Intent, int, int).

From docs.



回答2:

I found a solution with the help of @emandt.

I just added these lines of code in onStartCommand() :

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    Log.d(TAG, "Service Started");
    Notification notification = new NotificationCompat.Builder(this, CHANNELID)
            .setContentTitle("title")
            .setContentText("text")
            .setSmallIcon(R.drawable.baseline_pause_white_24)
            .build();
    startForeground(2001,notification);
    return START_NOT_STICKY;
}

According to docs the startForeground method :

If your service is started then also make this service run in the foreground, supplying the ongoing notification to be shown to the user while in this state...By default started services are background, meaning that their process won't be given foreground CPU scheduling (unless something else in that process is foreground)

Also,

If your app targets API level 26 or higher, the system imposes restrictions on using or creating background services unless the app itself is in the foreground. If an app needs to create a foreground service, the app should call startForegroundService(). That method creates a background service, but the method signals to the system that the service will promote itself to the foreground. Once the service has been created, the service must call its startForeground() method within five seconds.