Android 当应用程序在 Android M (6) 打开时,仅作业计划程序 运行 个作业
Android Job Scheduler only running jobs when app is open on Android M (6)
我正在尝试在我的 Xamarin Forms 应用程序的后台将 Android 作业计划程序添加到 运行 作业,但它似乎只在我打开该应用程序时 运行。
作业已正确安排,但应用程序关闭时未触发。当需要调用外部 API 作业以获取一些数据,然后需要使用该数据更新本地 SQLite 数据库时应该发生什么。
我正在 Android 6 (M) 的 OnePlus 2 上进行测试。
下面是我的作业服务实现。
[Service(Name = "com.sample.JobSchedulerService", Permission = "android.permission.BIND_JOB_SERVICE")]
public class JobSchedulerService : JobService
{
private readonly Service _service;
public JobSchedulerService()
{
_service = new Service();
}
public override bool OnStartJob(JobParameters jobParams)
{
Task.Run(() =>
{
var updated = _service.UpdateDataAsync(54, -2);
JobFinished(jobParams, !updated.Result);
});
return true;
}
public override bool OnStopJob(JobParameters jobParams)
{
return true;
}
}
下面是安排我的工作的代码。
[assembly: Xamarin.Forms.Dependency(typeof(DownloadJob))]
namespace IslamReminders.Droid.Services
{
public class DownloadJob : IDownloadJob
{
public void ScheduleJob(int jobId, long notificationRepeatMilliseconds)
{
var jobBuilder = JobScheduleHelpers.CreateJobBuilderUsingJobId<JobSchedulerService>(Application.Context, jobId)
.SetPeriodic(notificationRepeatMilliseconds)
.SetPersisted(true)
.Build();
var jobScheduler = (JobScheduler)Application.Context.GetSystemService(Context.JobSchedulerService);
var scheduleResult = jobScheduler.Schedule(jobBuilder);
}
}
}
下面是调用 DownloadJob 以从 App.cs OnStart 安排作业的代码。
protected override void OnStart()
{
// Handle when your app starts
var jobs = _dataAccess.GetJobs();
if (jobs.Any(x => !x.IsActive))
{
var inactiveJobs = jobs.Where(x => x.IsActive == false);
foreach (var job in inactiveJobs)
{
var notificationTimes = _dataAccess.GetNotificationTimesForJob(job.NotificationId);
foreach (var notificationTime in notificationTimes)
DependencyService.Get<IDownloadJob>().ScheduleJob(job.Id, (long)notificationTime.NotificationRepeat.TotalMilliseconds);
job.IsActive = true;
_dataAccess.UpdateJob(job);
}
}
}
我认为我已正确设置所有内容,但在应用程序关闭时无法正常工作。如有任何帮助,我们将不胜感激。
我最终更改了我的实现以使用 AlarmManager,因为这更适合我想要实现的目标,因为我需要在每天午夜后 运行 完成工作。
但是,我最终 运行 遇到了完全相同的问题,因为当应用程序关闭时我的工作不会 运行。当应用程序打开或处于后台时,代码会 运行 正常。
然后我做了一些进一步的分析,发现问题实际上与我试图使用 DependencyService 获取数据库路径有关。我收到的错误如下:
You MUST call Xamarin.Forms.Init(); prior to using it
应用程序关闭时它不工作的原因是因为 Xamarin.Forms 那时从未初始化,因此无法使用 DependencyService。我解决这个问题的方法是在广播接收器(或 JobSchedulerService)中获取数据库的路径,并将其传递给我的共享代码,然后按预期工作。
我没有使用 Job Scheduler 对此进行测试,因为我决定更改我的实现,但我相信这可能一直是 Job Scheduler 的问题。
希望这个解释可以帮助可能 运行 遇到类似问题的人。
我正在尝试在我的 Xamarin Forms 应用程序的后台将 Android 作业计划程序添加到 运行 作业,但它似乎只在我打开该应用程序时 运行。
作业已正确安排,但应用程序关闭时未触发。当需要调用外部 API 作业以获取一些数据,然后需要使用该数据更新本地 SQLite 数据库时应该发生什么。
我正在 Android 6 (M) 的 OnePlus 2 上进行测试。
下面是我的作业服务实现。
[Service(Name = "com.sample.JobSchedulerService", Permission = "android.permission.BIND_JOB_SERVICE")]
public class JobSchedulerService : JobService
{
private readonly Service _service;
public JobSchedulerService()
{
_service = new Service();
}
public override bool OnStartJob(JobParameters jobParams)
{
Task.Run(() =>
{
var updated = _service.UpdateDataAsync(54, -2);
JobFinished(jobParams, !updated.Result);
});
return true;
}
public override bool OnStopJob(JobParameters jobParams)
{
return true;
}
}
下面是安排我的工作的代码。
[assembly: Xamarin.Forms.Dependency(typeof(DownloadJob))]
namespace IslamReminders.Droid.Services
{
public class DownloadJob : IDownloadJob
{
public void ScheduleJob(int jobId, long notificationRepeatMilliseconds)
{
var jobBuilder = JobScheduleHelpers.CreateJobBuilderUsingJobId<JobSchedulerService>(Application.Context, jobId)
.SetPeriodic(notificationRepeatMilliseconds)
.SetPersisted(true)
.Build();
var jobScheduler = (JobScheduler)Application.Context.GetSystemService(Context.JobSchedulerService);
var scheduleResult = jobScheduler.Schedule(jobBuilder);
}
}
}
下面是调用 DownloadJob 以从 App.cs OnStart 安排作业的代码。
protected override void OnStart()
{
// Handle when your app starts
var jobs = _dataAccess.GetJobs();
if (jobs.Any(x => !x.IsActive))
{
var inactiveJobs = jobs.Where(x => x.IsActive == false);
foreach (var job in inactiveJobs)
{
var notificationTimes = _dataAccess.GetNotificationTimesForJob(job.NotificationId);
foreach (var notificationTime in notificationTimes)
DependencyService.Get<IDownloadJob>().ScheduleJob(job.Id, (long)notificationTime.NotificationRepeat.TotalMilliseconds);
job.IsActive = true;
_dataAccess.UpdateJob(job);
}
}
}
我认为我已正确设置所有内容,但在应用程序关闭时无法正常工作。如有任何帮助,我们将不胜感激。
我最终更改了我的实现以使用 AlarmManager,因为这更适合我想要实现的目标,因为我需要在每天午夜后 运行 完成工作。
但是,我最终 运行 遇到了完全相同的问题,因为当应用程序关闭时我的工作不会 运行。当应用程序打开或处于后台时,代码会 运行 正常。
然后我做了一些进一步的分析,发现问题实际上与我试图使用 DependencyService 获取数据库路径有关。我收到的错误如下:
You MUST call Xamarin.Forms.Init(); prior to using it
应用程序关闭时它不工作的原因是因为 Xamarin.Forms 那时从未初始化,因此无法使用 DependencyService。我解决这个问题的方法是在广播接收器(或 JobSchedulerService)中获取数据库的路径,并将其传递给我的共享代码,然后按预期工作。
我没有使用 Job Scheduler 对此进行测试,因为我决定更改我的实现,但我相信这可能一直是 Job Scheduler 的问题。
希望这个解释可以帮助可能 运行 遇到类似问题的人。