java - 关闭应用程序时清除警报和作业?
问题描述
所以,我正在尝试在后台运行一项服务,该服务可以将一些应用程序数据发送到我的服务器到目前为止,我已经尝试使用AlarmManager、JobScheduler 类定期运行该服务,但它没有用,因为创建的任何警报和计划的作业都已清除由于应用程序已关闭(此处关闭并不意味着强制停止)。我环顾四周,看到了很多类似用例(但较旧的 android 版本)和相同的清除问题的 StackOverflow 问题,但我发现没有具体的答案或实现有效。(这是最新版本的android的问题吗?)
我的用例是每天从应用程序上传一到两次小数据(in/kbs),以维护应用程序的使用跟踪。
因为我不能指望用户整天保持他的应用程序打开......
- 如所解释的,如何实现这种周期性?
更新-1
根据@Kabumere的回答和android dev docs的一些帮助,我使用了WorkManager并在
预期的行为(现在)
下面尝试了这段代码
,无论应用程序是否关闭(即30 6 到 7 之间的最小间隔)
实际行为
- 应用程序专注于测试设备(genymotion android 9)
- 08:47 onCreate 安排第一个作业并运行
- 应用程序已关闭但最近出现
- 09:02 第二个作业运行(相隔 15 分钟)
- 应用程序现在从最近关闭
- // 30 分钟内没有更多日志,作业未开始
- 09:36 应用程序手动启动,没有按逻辑排队
- 作业以 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();
}
解决方案
我建议使用WorkManager API而不是创建服务。
使用 WorkManager,您可以将PeriodicWorkRequest排入队列,该请求将以您在其Builder 构造函数中设置的时间间隔运行(例如每 24 小时运行一次)。通过 WorkManager 安排的作业不应在应用关闭时删除,将在设备重启等不同事件时自动重新安排,即使应用在后台也可以运行。
您还可以在 WorkRequests 上设置约束,以便您可以指定诸如“仅在我们有任何类型的数据连接时才尝试运行此作业”(setRequiredNetworkType(NetworkType.CONNECTED)
)。这对于您需要发送数据的用例很有用,这需要一些连接。
推荐阅读
- python - ORM:发票。v10 中的 compute_taxes 的 v14 等价物是什么?
- powershell - 多行注释未显示在来自 ADO 发布管道中的手动干预作业的电子邮件通知中
- sql - 如何在 SQL Server 中显示交叉联接表中所有项目的计数
- android - Compress Video with FFmpeg
- python - Python 如何编辑/更新 GitHub 要点?
- ios - 将 Firebase 添加到动态框架中时,没有这样的模块“Firebase”
- flutter - Flutter:具有默认材料压延设计的 DateRangePicker
- mongodb - 在猫鼬中查找条件
- angular - 同一网址页面中的 Ionic 5 路由
- java - java中第n次出现的子字符串