写点什么

深入理解 JobScheduler 与 JobService 的使用

用户头像
Android架构
关注
发布于: 36 分钟前

private void onJobStartClick() {JobScheduler jobScheduler = (JobScheduler) getSystemService(JOB_SCHEDULER_SERVICE);ComponentName componentName = new ComponentName(this, MyJobService.class);JobInfo jobinfo = new JobInfo.Builder(JOB_INFO_ID, componentName).setPeriodic(JOB_PERIODIC).build();}


周期 periodic 设置为 5 秒->运行,会发现 JobService 没有被启动,为什么? #####setPeriodic 的最小执行间隔 源码里来找答案:android/frameworks/base/core/java/android/app/job/JobInfo.java


/* Minimum interval for a periodic job, in milliseconds. /private static final long MIN_PERIOD_MILLIS = 15 * 60 * 1000L; // 15 minutes/ Minimum flex for a periodic job, in milliseconds. */private static final long MIN_FLEX_MILLIS = 5 * 60 * 1000L; // 5 minutes


/**


  • Specify that this job should recur with the provided interval, not more than once per

  • period. You have no control over when within this interval this job will be executed,

  • only the guarantee that it will be executed at most once within this interval.

  • Setting this function on the builder with {@link #setMinimumLatency(long)} or

  • {@link #setOverrideDeadline(long)} will result in an error.

  • @param intervalMillis Millisecond interval for which this job will repeat./public Builder setPeriodic(long intervalMillis) {return setPeriodic(intervalMillis, intervalMillis);}/*

  • Specify that this job should recur with the provided interval and flex. The job can

  • execute at any time in a window of flex length at the end of the period.

  • @param intervalMillis Millisecond interval for which this job will repeat. A minimum

  • @param flexMillis Millisecond flex for this job. Flex is clamped to be at least


*/public Builder setPeriodic(long intervalMillis, long flexMillis) {mIsPeriodic = true;mIntervalMillis = intervalMillis;mFlexMillis = flexMillis;mHasEarlyConstraint = mHasLateConstraint = true;return this;}


/**


  • Query the minimum interval allowed for periodic scheduled jobs. Attempting

  • to declare a smaller period that this when scheduling a job will result in a

  • job that is still periodic, but will run with this eff


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码


ective period.*


  • @return The minimum available interval for scheduling periodic jobs, in milliseconds./public static final long getMinPeriodMillis() {return MIN_PERIOD_MILLIS;}/*

  • Set to the interval between occurrences of this job. This value is <b>not</b> set if the

  • job does not recur periodically.*/public long getIntervalMillis() {final long minInterval = getMinPeriodMillis();return intervalMillis >= minInterval ? intervalMillis : minInterval;}


总结几个要点:


  • 可以看到系统默认设置了一个最小间隔时间 15 分钟,在获取执行间隔时,会先比较最小间隔时间和设置的间隔时间,取其中大的那个。所以 setPeriodic 设置时间小于 15 分钟是不会生效的。

  • flexMillis 参数是用来设置周期任务执行的活动时间的,这意味着 JobScheduler 规划的任务不是在精确的时间执行的。并且这个时间也是有最小值的,系统默认 5 分钟。

  • setMinimumLatency 和 setOverrideDeadline 不能同 setPeriodic 一起使用,会引起报错,另外还有一些其他规则,看源码:


/**


  • @return The job object to hand to the JobScheduler. This object is immutable.*/public JobInfo build() {// Allow jobs with no constraints - What am I, a database?if (!mHasEarlyConstraint && !mHasLateConstraint && mConstraintFlags == 0 &&mNetworkType == NETWORK_TYPE_NONE &&mTriggerContentUris == null) {throw new IllegalArgumentException("You're trying to build a job with no " +"constraints, this is not allowed.");}// Check that a deadline was not set on a periodic job.if (mIsPeriodic) {if (mMaxExecutionDelayMillis != 0L) {throw new IllegalArgumentException("Can't call setOverrideDeadline() on a " +"periodic job.");}if (mMinLatencyMillis != 0L) {throw new IllegalArgumentException("Can't call setMinimumLatency() on a " +"periodic job");}if (mTriggerContentUris != null) {throw new IllegalArgumentException("Can't call addTriggerContentUri() on a " +"periodic job");}}if (mIsPersisted) {if (mTriggerContentUris != null) {throw new IllegalArgumentException("Can't call addTriggerContentUri() on a " +"persisted job");}if (!mTransientExtras.isEmpty()) {throw new IllegalArgumentException("Can't call setTransientExtras() on a " +"persisted job");}if (mClipData != null) {throw new IllegalArgumentException("Can't call setClipData() on a " +"persisted job");}}if (mBackoffPolicySet && (mConstraintFlags & CONSTRAINT_FLAG_DEVICE_IDLE) != 0) {throw new IllegalArgumentException("An idle mode job will not respect any" +" back-off policy, so calling setBackoffCriteria with" +" setRequiresDeviceIdle is an error.");}JobInfo job = new JobInfo(this);....return job;}


####如何查看自己的 JobService 的运行? adb 给我们提供了 dumpsys 工具: adb shell dumpsys jobscheduler


JOB #u0a122/10001: 945a633 com.fantasy.android.demo/.android.job.MyJobServiceu0a122 tag=job/com.fantasy.android.demo/.android.job.MyJobServiceSource: uid=u0a122 user=0 pkg=com.fantasy.android.demoJobInfo:Service: com.fantasy.android.demo/.android.job.MyJobServicePERIODIC: interval=+1h0m0s0ms flex=+1h0m0s0msRequires: charging=false batteryNotLow=false deviceIdle=falseBackoff: policy=1 initial=+30s0msHas early constraintHas late constraintRequired constraints: TIMING_DELAY DEADLINESatisfied constraints: APP_NOT_IDLE DEVICE_NOT_DOZINGUnsatisfied constraints: TIMING_DELAY DEADLINETracking: TIMEEnqueue time: -5m38s906msRun time: earliest=+54m21s65ms, latest=+1h54m21s65ms

用户头像

Android架构

关注

还未添加个人签名 2021.10.31 加入

还未添加个人简介

评论

发布
暂无评论
深入理解JobScheduler与JobService的使用