Android中定时作业执行的当前最佳实践
由于我一直在与Android Oreo后台限制作斗争,我问自己,使用AlarmManager是否是将作业执行时间安排到凌晨03:00的最佳方式。我看到一些人使用JobScheduler,但它似乎不太适合每天在给定时间执行任务 我试着在AlarmManager上安装一个BroadcastReceiver,然后将BroadcastReceiver插入理论上的自启动服务中,但由于应用程序在后台无法调用startService,这也不能正常工作,而且似乎有点错误 我错过什么了吗?目前的做法是什么? 显然是有办法的,否则信使、游戏和其他应用程序将无法像他们那样工作Android中定时作业执行的当前最佳实践,android,time,alarmmanager,Android,Time,Alarmmanager,由于我一直在与Android Oreo后台限制作斗争,我问自己,使用AlarmManager是否是将作业执行时间安排到凌晨03:00的最佳方式。我看到一些人使用JobScheduler,但它似乎不太适合每天在给定时间执行任务 我试着在AlarmManager上安装一个BroadcastReceiver,然后将BroadcastReceiver插入理论上的自启动服务中,但由于应用程序在后台无法调用startService,这也不能正常工作,而且似乎有点错误 我错过什么了吗?目前的做法是什么? 显然
public class BackgroundTaskWorker extends Worker {
public BackgroundTaskWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) {
super(context, workerParams);
}
@Override
public Result doWork() {
Log.i("WORKING","DOING SOME WORK");
Context con = getApplicationContext();
SharedPreferences preferences = con.getSharedPreferences(MainActivity.sharedPrefs, Context.MODE_PRIVATE);
SharedPreferences.Editor editPrefs = preferences.edit();
int day = Calendar.getInstance().get(Calendar.DAY_OF_MONTH);
String s_day = preferences.getString("DAY","0");
int old_day = Integer.parseInt(s_day);
if(old_day == 0){
Log.i("WORKING","old_day default");
editPrefs.putString("DAY",Integer.toString(day));
editPrefs.commit();
return Result.success();
}
else if(day == old_day) {
Log.i("WORKING", "day=old_day default");
return Result.success();
}
else {
Log.i("WORKING","old_day change");
editPrefs.putString("DAY",Integer.toString(day));
editPrefs.commit();
Log.d("BISASAM","triggered");
DateFormat date = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss", Locale.GERMANY);
Date dat = new Date();
Log.d("TRIGGERDATE",date.format(dat));
editPrefs.putString("REC", "Receiver called "+date.format(dat));
NotificationCompat.Builder builder= new NotificationCompat.Builder(con,"ID");
builder.setContentTitle("ALARM FIRED");
builder.setContentText("WORKER");
builder.setPriority(NotificationCompat.PRIORITY_DEFAULT);
builder.setSmallIcon(R.drawable.kreuz);
if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.O) {
Log.d("BUILDCHECK","correct");
CharSequence name = "NotChannel";
String desc = "Test Channel for Planer";
int importance = NotificationManager.IMPORTANCE_DEFAULT;
NotificationChannel channel = new NotificationChannel("NOT",name,importance);
channel.setDescription(desc);
NotificationManager notManager = con.getSystemService(NotificationManager.class);
notManager.createNotificationChannel(channel);
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(con);
builder.setChannelId("NOT");
notificationManager.notify(1,builder.build());
}
//TODO Test Tageswechsel Wiederholende Tasks
String today = preferences.getString("0",null);
String tomorrow = preferences.getString("1",null);
String next_week = preferences.getString("7",null);
String next_month = preferences.getString("30",null);
if(today != null) {
String[] repetitive = today.split(" ");
for (int j = 1; j < repetitive.length; j += 2) {
Log.d("PIKACHU",repetitive[j-1]);
switch(repetitive[j]){
case "1":
if(tomorrow!=null)
tomorrow += ","+ repetitive[j-1]+" "+repetitive[j];
else
tomorrow=repetitive[j-1]+" "+repetitive[j];
break;
case "7":
if(next_week!=null)
next_week += ","+ repetitive[j-1]+" "+repetitive[j];
else
next_week=repetitive[j-1]+" "+repetitive[j];
break;
case "30":
if(next_month!=null)
next_month += ","+ repetitive[j-1]+" "+repetitive[j];
else
next_month=repetitive[j-1]+" "+repetitive[j];
break;
default:
}
}
}
Log.d("PUTTING",tomorrow);
Log.d("PUTTING",next_week);
Log.d("PUTTING",next_month);
editPrefs.putString("1",tomorrow);
editPrefs.putString("7",next_week);
editPrefs.putString("30",next_month);
editPrefs.commit();
ArrayList<String> month = new ArrayList<>();
for (int i = 0; i < Jobs.month_length; i++) {
month.add(preferences.getString(Integer.toString(i),""));
}
for (int i=1;i<Jobs.month_length;i++){
month.set(i-1,month.get(i));
}
month.set(30,"");
for(int i=0;i<Jobs.month_length;i++){
editPrefs.putString(Integer.toString(i),month.get(i));
}
Log.d("COMMITED",month.toString());
editPrefs.commit();
}
// Indicate success or failure with your return value:
return Result.success();
}
}
每次启动应用程序时调用registerWorker=>使用WorkManager在后台和前台调度任务
定期请求示例
创建一个工人类
public class WorkerClass extends Worker {
@Override
public Worker.WorkerResult doWork() {
// Do the work here
// Indicate success or failure with your return value:
return WorkerResult.SUCCESS;
// (Returning RETRY tells WorkManager to try this task again
// later; FAILURE says not to try again.)
}
}
现在叫这个班
一次性请求的示例
OneTimeWorkRequest request= new OneTimeWorkRequest.Builder(WorkerClass .class)
.setInitialDelay(delayedTime, TimeUnit.MILLISECONDS)
.addTag("TAG")
.build();
WorkManager.getInstance().enqueueUniquePeriodicWork("TAG", ExistingPeriodicWorkPolicy.KEEP, request);
其中delayedTime是计算完成任务的时间
将此添加到build.gradle中
查看最新的发布文档
你也可以转换你的时间
WorkManager是否可以这样做?将任务设置为始终在给定时间执行?对于Android Oreo和更高版本来说,这是背景安全的吗?是的,它将在这里工作。似乎不可能在特定时间运行它,也不可能重新执行任务?这将如何实现?现在检查我的答案,我要计算一次偏移量,然后工作将始终在时间=当前时间+偏移量?延迟=当前时间,单位为毫秒-特定时间触发单位为毫秒谢谢,我会尝试,但最后一件事。无法解析build.gradle的行。你知道为什么吗?
public class WorkerClass extends Worker {
@Override
public Worker.WorkerResult doWork() {
// Do the work here
// Indicate success or failure with your return value:
return WorkerResult.SUCCESS;
// (Returning RETRY tells WorkManager to try this task again
// later; FAILURE says not to try again.)
}
}
OneTimeWorkRequest request= new OneTimeWorkRequest.Builder(WorkerClass .class)
.setInitialDelay(delayedTime, TimeUnit.MILLISECONDS)
.addTag("TAG")
.build();
WorkManager.getInstance().enqueueUniquePeriodicWork("TAG", ExistingPeriodicWorkPolicy.KEEP, request);
implementation 'android.arch.work:work-runtime:2.1.0-alpha02'