Job Scheduler无法取消系统uid的作业

时间:2018-06-26 13:26:34

标签: android android-jobscheduler

尝试取消应用程序中的所有作业时,我在logcat中收到以下异常

06-26 11:27:54.866 E/JobSchedulerService( 1246): Can't cancel all jobs for system uid
06-26 11:27:54.866 E/JobSchedulerService( 1246): android.util.Log$TerribleFailure: Can't cancel all jobs for system uid
06-26 11:27:54.866 E/JobSchedulerService( 1246):    at android.util.Log.wtf(Log.java:299)
06-26 11:27:54.866 E/JobSchedulerService( 1246):    at android.util.Slog.wtfStack(Slog.java:98)
06-26 11:27:54.866 E/JobSchedulerService( 1246):    at com.android.server.job.JobSchedulerService.cancelJobsForUid(JobSchedulerService.java:788)
06-26 11:27:54.866 E/JobSchedulerService( 1246):    at com.android.server.job.JobSchedulerService$JobSchedulerStub.cancelAll(JobSchedulerService.java:2033)
06-26 11:27:54.866 E/JobSchedulerService( 1246):    at android.app.job.IJobScheduler$Stub.onTransact(IJobScheduler.java:119)
06-26 11:27:54.866 E/JobSchedulerService( 1246):    at android.os.Binder.execTransact(Binder.java:697)

有人也遇到此错误吗?我似乎在任何地方都找不到答案。

取消作业的代码很简单,如下所示:

public static void cancelAllJobs(@NonNull Context context) {
    JobScheduler jobScheduler = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
    if (jobScheduler != null) {
        jobScheduler.cancelAll();
        Timber.d("All jobs are canceled.");
    } else {
        Timber.w("Job scheduler is not available.");
    }
}

请注意,清单

中将我的应用声明为系统
android:sharedUserId="android.uid.system"

1 个答案:

答案 0 :(得分:4)

如果运行:adb shell dumpsys jobscheduler,则可以查看在系统uid(#1000)下安排的所有作业。

在具有共享uid的应用程序下安排的作业必须确保在使用该共享uid的所有软件包中,其作业ID是唯一的。来自文档:"ID must be unique across all clients of the same uid (not just the same package)." cancelAll()API将取消调用uid下的所有作业,而不仅仅是取消调用包中的作业。我猜想Android会限制系统uid的程序包取消所有系统uid作业,以确保不会意外取消作业。

您真的要取消系统uid下所有应用程序/程序包中的所有作业吗?

我有几个将Jobscheduler与系统uid一起使用的应用程序,并使用以下代码取消特定作业。

public static void cancelJob(Context mContext, int jobID) {
    JobScheduler scheduler = (JobScheduler)
            mContext.getSystemService(Context.JOB_SCHEDULER_SERVICE);

    for (JobInfo jobInfo : scheduler.getAllPendingJobs()) {
        if (jobInfo.getId() == jobID) {
            scheduler.cancel(jobID);
            Log.i(TAG,"Cancelled Job with ID:" + jobID);
        }
    }
}

我刚遇到的另一个好帖子: https://commonsware.com/blog/2017/06/07/jobscheduler-job-ids-libraries.html