首页 > 解决方案 > 关闭应用程序时清除警报和作业?

问题描述


所以,我正在尝试在后台运行一项服务,该服务可以将一些应用程序数据发送到我的服务器到目前为止,我已经尝试使用AlarmManager、JobScheduler 类定期运行该服务,但它没有用,因为创建的任何警报和计划的作业都已清除由于应用程序已关闭(此处关闭并不意味着强制停止)。我环顾四周,看到了很多类似用例(但较旧的 android 版本)和相同的清除问题的 StackOverflow 问题,但我发现没有具体的答案或实现有效。(这是最新版本的android的问题吗?)

我的用例是每天从应用程序上传一到两次小数据(in/kbs),以维护应用程序的使用跟踪。

因为我不能指望用户整天保持他的应用程序打开......



更新-1

根据@Kabumere的回答和android dev docs的一些帮助,我使用了WorkManager并在
预期的行为(现在)
下面尝试了这段代码 ,无论应用程序是否关闭(即30 6 到 7 之间的最小间隔)
实际行为

  1. 应用程序专注于测试设备(genymotion android 9)
  2. 08:47 onCreate 安排第一个作业并运行
  3. 应用程序已关闭但最近出现
  4. 09:02 第二个作业运行(相隔 15 分钟)
  5. 应用程序现在从最近关闭
  6. // 30 分钟内没有更多日志,作业未开始
  7. 09:36 应用程序手动启动,没有按逻辑排队
  8. 作业以 15 分钟间隔继续
2020-08-05 08:47:53.260 7746-7746/com.example.workmanagerapi D/debugTag: Scheduling
2020-08-05 08:47:53.655 7746-7802/com.example.workmanagerapi D/debugTag: DOING SOME WORK !!!
2020-08-05 09:02:53.732 7746-8007/com.example.workmanagerapi D/debugTag: DOING SOME WORK !!!
2020-08-05 09:36:47.165 8347-8347/com.example.workmanagerapi D/debugTag: Already Scheduled
2020-08-05 09:36:47.193 8347-8376/com.example.workmanagerapi D/debugTag: DOING SOME WORK !!!
2020-08-05 09:51:47.269 8347-8486/com.example.workmanagerapi D/debugTag: DOING SOME WORK !!!

MainActivity.java

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        SharedPreferences SP = getSharedPreferences("prefs",MODE_PRIVATE);
        SharedPreferences.Editor editor = SP.edit();
        boolean enqueue = SP.getBoolean("enqueue", false);
        if(enqueue) {
            Log.d("debugTag", "Already Scheduled");
        }
        else {
            Log.d("debugTag", "Scheduling");
            doWork();
            editor.putBoolean("enqueue",true);
            editor.apply();
        }
    }

    private void doWork() {
        PeriodicWorkRequest.Builder myWorkBuilder = new PeriodicWorkRequest.Builder(MyWorker.class, 1, TimeUnit.MINUTES);
        // i read on docs that this time limit will default to (5+15) minutes minimum
        PeriodicWorkRequest myWork = myWorkBuilder.build();
        WorkManager.getInstance(this).enqueue(myWork);
    }
}

MyWorker.java

public class MyWorker extends Worker {
    public MyWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) {
        super(context, workerParams);
    }

    @NonNull
    @Override
    public Result doWork() {
        Log.d("debugTag", "DOING SOME WORK !!!");
        return Result.success();
    }

标签: javaandroidservicealarmmanagerandroid-jobscheduler

解决方案


我建议使用WorkManager API而不是创建服务。

使用 WorkManager,您可以将PeriodicWorkRequest排入队列,该请求将以您在其Builder 构造函数中设置的时间间隔运行(例如每 24 小时运行一次)。通过 WorkManager 安排的作业不应在应用关闭时删除,将在设备重启等不同事件时自动重新安排,即使应用在后台也可以运行。

您还可以在 WorkRequests 上设置约束,以便您可以指定诸如“仅在我们有任何类型的数据连接时才尝试运行此作业”(setRequiredNetworkType(NetworkType.CONNECTED))。这对于您需要发送数据的用例很有用,这需要一些连接。


推荐阅读