Android 服务:从 phone(全部清除)任务中杀死或从任务堆栈中删除后重新启动

Android Service: Restarting once killed or removed from task stack from phone(Clear All) tasks

我正在尝试 运行 我的服务在后台持续运行。我知道它会耗尽大量电池,但它对我来说仍然是一个用例。

案例 1: 使用 startService(intent) 方法启动 BackgroundService。 案例 2: 使用 bindService(intent,serviceConnection, Context.BIND_AUTO_CREATE);

启动 BoundService

在这两种情况下,我的服务 onStartCommand 代码如下所示,

 @Override
public int onStartCommand(Intent intent, int flags, int startId) {
    new Thread(new Runnable() {
        @Override
        public void run() {
            while(count < 10000){
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                count++;

            }

        }
    }).start();
    // TODO: flag not start itself when stopped
    // TODO: use START_STICKY to keep running
    return START_STICKY;
}

当我的服务不死的情况意味着它会保持 运行ning:

案例 1: 如果我按下 HOME 键。 情况 2: 如果我按回车键退出应用程序。

我的服务肯定被kill的场景:

案例 1: 如果我从 phone 的任务堆栈中删除我的应用程序。 情况 2: 我转到设置并停止服务。

我希望我的服务在上述任何一种情况下被杀死后立即启动。

我已经从 Whosebug 中引用了很多问题来这样做,

  @Override
    public void onDestroy() {
        super.onDestroy();

        startService(new Intent(this, BackgroundService.class));
    }

    @Override
    public void onTaskRemoved(Intent rootIntent) {
        super.onTaskRemoved(rootIntent);

        startService(new Intent(this, BackgroundService.class));

    }

但是onDestroy()肯定不是那种每次都会调用的方法。我已经在我的日志中查看过了。

如果用户在您的应用程序上执行 "force stop",您的 Service 将被终止,您无法阻止它。您也无法自动重启 Service,因为用户已告知 Android 它不希望您的应用程序再 运行。用户必须手动重启您的应用。

如果您从 "list of recent tasks" 中删除您的应用程序,Android 将终止托管您的应用程序的 OS 进程。假设你的Service也在这个OS进程中运行ning,它也会被杀死。在这种情况下,假设您已从 onStartCommand() 返回 START_STICKY,Android 将在新的 OS 进程中重新启动您的 Service

在某些设备(小米、华为、其他一些中国手机、一些 LG 和联想设备)中,您的应用必须手动添加到 "protected apps" 或 "apps that are allowed to run in the background" 列表中才能使用Android 自动重启您的 Service。在这些设备上,Android 不会自动重启您的 Service,即使您已从 onStartCommand() 返回 START_STICKY

另见 Situations when a Service's onDestroy() method doesn't get called?

我使用以下代码段使用 RTC 重复报警,

 Context ctx = getApplicationContext();
        Calendar cal = Calendar.getInstance();
        AlarmManager am = (AlarmManager) ctx.getSystemService(Context.ALARM_SERVICE);
        long interval = 100 * 5;
        Intent serviceIntent = new Intent(ctx, BackgroundService.class);
        PendingIntent servicePendingIntent =
                PendingIntent.getService(ctx,
                        BackgroundService.SERVICE_ID,
                        serviceIntent,
                        PendingIntent.FLAG_UPDATE_CURRENT); 
        am.setRepeating(
                AlarmManager.RTC,
                cal.getTimeInMillis(),
                interval,
                servicePendingIntent
        );

对于 PendingIntent.FLAG_UPDATE_CURRENT,它正在更新当前服务本身,还有其他标志也会取消现有服务并启动新服务。

BackgroundService.SERVICE_ID,在服务中创建了静态。

这个Android开发者官方文档帮了我,

Alarms (based on the AlarmManager class) give you a way to perform time-based operations outside the lifetime of your application.

https://developer.android.com/training/scheduling/alarms.html#set