在JobIntentService的幕后

在本文中,我们将讨论JobIntentService的一个问题,关于这个问题,Google Bug Tracker中的相应资源和报告存在很多问题。 此外,从所有方面来看,Google都不认为它是bug并关闭这些报告的原因。


引言


JobIntentServices是为后台工作而创建的。 当在后台使用服务的功能消失时,它们已在Android 8及更高版本中广泛使用。
实际上,它们在后台替换服务,并且也受任务计划程序(JobScheduler)的控制。


因此,该系统具有在后台控制任务进度并控制唤醒锁自身的能力,这使得优化设备的电池消耗并避免开发人员错误使用唤醒锁成为可能。 这些步骤可以最大程度地减少设备无法进入睡眠模式(打ze模式)的情况,这又会影响电池的节省。


简要介绍JobIntentService


本质上,JobIntentService在任务计划程序(JobScheduler)的控制下是相同的IntentService。


在AsyncTask的后台线程中运行。


在Android 4.4及更低版本中,通常使用IntentService。


详细说明可在文档中找到。


生命周期与陷阱


两种任务都有相同的生命周期。 任务由Handler控制并具有状态。


尽管无法从外部访问这些状态,但是在某些情况下,系统会引发应用程序崩溃的异常。 对于许多开发人员而言,这些行为是一个问题和令人头疼的问题,不幸的是没有简单的解决方案。 首先,我们研究任务的状态和生命周期,然后考虑可能的解决方案。


任务状态序列


图片
绑定 -任务创建状态(服务绑定)超时18秒。
正在启动 -任务启动状态,超时8秒。
执行-任务执行状态,超时10分钟。
STOPPING-任务停止状态(例如,在调用cancel()之后),超时8秒。
已完成-已完成任务的最终状态,任务生命周期中的最后一个状态。


简化的任务生命周期图


图片
每个任务状态都有自己的超时时间。 超时后,任务将被中断,无论其状态如何。 实际上,这是一种超时机制,因为 超时后,系统引发类型为java.lang.SecurityException的异常,应用程序崩溃,并显示以下消息: Caller no longer running, last stopped +1s600ms because: timed out while starting其中+1s600ms是超时以来经过的时间引发异常的那一刻,“原因”( because: timed out while starting时超时)指示超时到期时任务所处的状态。


结论


经验表明,这些例外情况是在加载正常的应用程序中发现的。


为支持此问题,可以在弱设备和顶部设备上进行观察。 超时消息引发的异常也表明了此问题。 因此,有关卸载应用程序和优化JobIntentServices使用的决定建议自己避免例如并行启动多个JobIntentServices的情况。 第二种解决方案是使用JobService,在某些情况下比第一种选择更琐碎,有时甚至更复杂。


另外,如果您使用Google搜索此问题,则可能会发现其他用于解决此问题的“可疑”选项,例如,您可以看到以下链接:


选项1
选项2
选项3


聚苯乙烯


目前,Google正在准备好替代JobService和JobIntentService-androidx.work包中的Worker和WorkManger。


不幸的是,这些工具尚未准备好投入生产并且存在许多错误,但是正如测试所示,现在它们已经解决了上述问题。

Source: https://habr.com/ru/post/zh-CN432576/


All Articles