何时调用 JobScheduler.schedule()
When to call JobScheduler.schedule()
我想实现的是一个每小时从服务器获取数据的后台服务。我希望此服务可以在启动后定期 运行。因此,我选择使用JobScheduler来实现这个功能。
val jobScheduler = getSystemService(Context.JOB_SCHEDULER_SERVICE) as JobScheduler
val builder = JobInfo.Builder(1, ComponentName(this, PullDataJob::class.java))
.setPeriodic(1000L * 60 * 60) // one hour
.setRequiredNetworkType(NETWORK_TYPE_ANY)
.setPersisted(true)
jobScheduler.schedule(builder.build())
这是我目前的代码,放在onCreate()
里面。但是我发现如果我把JobScheduler.schedule()
放在onCreate()
里,每次打开应用都会自动执行这个服务
即使用户在系统启动后从未打开该应用程序,也可以定期将上述代码放置在什么位置 运行?
您的作业是定期执行的(每小时一次),所以一旦它是 运行 第一次,JobScheduler.schedule()
应该 永远不会 被再次调用。
完成这个很容易,一旦你第一次调用 JobScheduler.schedule()
,注册它已经被安排的事实,只有 运行 当你确定你的工作有以前从未 运行。
public static final String IS_JOB_FIRST_RUN = "job scheduled";
...
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
if (preferences.getBoolean(IS_JOB_FIRST_RUN, true)) {
// your code
JobScheduler.schedule();
preferences.edit().putBoolean(IS_JOB_FIRST_RUN, false).apply();
}
哈基姆是对的,你应该只安排一次。
如果您两次使用相同的 JobId 安排作业,文档说明如下:
Will replace any currently scheduled job with the same ID with the new information in the JobInfo. If a job with the given ID is currently running, it will be stopped.
但我会以不同于 hakeem 的方式解决问题。您不应将此信息保存在 Sharedpreference 中,而应使用 JobScheduler 来确定是否已安排具有您的 ID 的作业。这样你会更加健壮,并且会重新安排工作,以防发生一些奇怪的事情并且你的工作不再被安排。
代码:
public static boolean isJobServiceOn( Context context ) {
JobScheduler scheduler = (JobScheduler) context.getSystemService( Context.JOB_SCHEDULER_SERVICE ) ;
boolean hasBeenScheduled = false ;
for ( JobInfo jobInfo : scheduler.getAllPendingJobs() ) {
if ( jobInfo.getId() == RETRIEVE_DATA_JOB_ID ) {
hasBeenScheduled = true ;
break ;
}
}
return hasBeenScheduled ;
}
安排作业时,您可以使用此功能来确定我当前是否安排了作业。
我想实现的是一个每小时从服务器获取数据的后台服务。我希望此服务可以在启动后定期 运行。因此,我选择使用JobScheduler来实现这个功能。
val jobScheduler = getSystemService(Context.JOB_SCHEDULER_SERVICE) as JobScheduler
val builder = JobInfo.Builder(1, ComponentName(this, PullDataJob::class.java))
.setPeriodic(1000L * 60 * 60) // one hour
.setRequiredNetworkType(NETWORK_TYPE_ANY)
.setPersisted(true)
jobScheduler.schedule(builder.build())
这是我目前的代码,放在onCreate()
里面。但是我发现如果我把JobScheduler.schedule()
放在onCreate()
里,每次打开应用都会自动执行这个服务
即使用户在系统启动后从未打开该应用程序,也可以定期将上述代码放置在什么位置 运行?
您的作业是定期执行的(每小时一次),所以一旦它是 运行 第一次,JobScheduler.schedule()
应该 永远不会 被再次调用。
完成这个很容易,一旦你第一次调用 JobScheduler.schedule()
,注册它已经被安排的事实,只有 运行 当你确定你的工作有以前从未 运行。
public static final String IS_JOB_FIRST_RUN = "job scheduled";
...
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
if (preferences.getBoolean(IS_JOB_FIRST_RUN, true)) {
// your code
JobScheduler.schedule();
preferences.edit().putBoolean(IS_JOB_FIRST_RUN, false).apply();
}
哈基姆是对的,你应该只安排一次。 如果您两次使用相同的 JobId 安排作业,文档说明如下:
Will replace any currently scheduled job with the same ID with the new information in the JobInfo. If a job with the given ID is currently running, it will be stopped.
但我会以不同于 hakeem 的方式解决问题。您不应将此信息保存在 Sharedpreference 中,而应使用 JobScheduler 来确定是否已安排具有您的 ID 的作业。这样你会更加健壮,并且会重新安排工作,以防发生一些奇怪的事情并且你的工作不再被安排。
代码:
public static boolean isJobServiceOn( Context context ) {
JobScheduler scheduler = (JobScheduler) context.getSystemService( Context.JOB_SCHEDULER_SERVICE ) ;
boolean hasBeenScheduled = false ;
for ( JobInfo jobInfo : scheduler.getAllPendingJobs() ) {
if ( jobInfo.getId() == RETRIEVE_DATA_JOB_ID ) {
hasBeenScheduled = true ;
break ;
}
}
return hasBeenScheduled ;
}
安排作业时,您可以使用此功能来确定我当前是否安排了作业。