3

我创建了一个服务,它的工作是在用户关闭应用程序时清除通知。一切运行良好,但有时当应用程序在后台运行超过 1 分钟时,服务会被终止(这意味着通知不会被取消)。为什么会这样?我认为停止服务的唯一方法是使用 stopSelf() 或 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();
    }
}

我从启动画面 Activity 启动服务,如下所示:startService(new Intent(this, OnClearFromRecentService.class));

这里还有一些日志消息: 在此处输入图像描述

4

2 回答 2

1

我在@emandt 的帮助下找到了解决方案。

我刚刚在 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;
}

根据文档 startForeground 方法:

如果您的服务已启动,则还要使该服务在前台运行,提供在此状态下向用户显示的持续通知...默认情况下,启动的服务是后台,这意味着它们的进程不会获得前台 CPU调度(除非该进程中的其他东西是前台)

还,

如果您的应用程序以 API 级别 26 或更高级别为目标,系统会限制使用或创建后台服务,除非应用程序本身位于前台。如果应用需要创建前台服务,应用应该调用startForegroundService()。该方法创建了一个后台服务,但该方法向系统发出信号,该服务将把自己提升到前台。创建服务后,服务必须在五秒内调用其startForeground()方法。

于 2018-07-21T18:21:52.587 回答
1

尝试返回START_STICKY表单 onStartCommand。
然后系统将尝试重新创建。
检查这个官方文档。

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

如果您还希望重新交付 Intent,您也可以尝试重新发送 START_REDELIVER_INTENT。

START_REDELIVER_INTENT

从 onStartCommand(Intent, int, int) 返回的常量:如果该服务的进程在启动时被杀死(在从 onStartCommand(Intent, int, int) 返回之后),那么它将被安排重新启动和最后交付的 Intent通过 onStartCommand(Intent, int, int) 再次重新交付给它。

来自文档。

于 2018-07-21T17:46:06.113 回答