Background
我想使用棒棒糖上提供的新 JobScheduler API,但遗憾的是它没有用于 Lollipop 之前的官方端口。
但是,有GcmTaskService,它提供了非常相似的功能。
问题所在
这个 API 是相当新的,所以很少有地方可以查找如何使用它的信息(例如,这里和这里(。
问题
我对这个新 API 有几个问题:
-
似乎它需要使用Google Play服务(这里((除了使用Lollipop版本的Android时,它将使用普通的JobScheduler(。如果 Google Play 服务不可用,我该怎么办?
-
似乎即使我对重复的任务使用了"setPersisted(true(",当我重新启动设备时,也不会再次调用该任务。怎么来了?编辑:那是因为我错过了RECEIVE_BOOT_COMPLETED的许可。
-
任务的默认行为是什么,如果我不使用"setRequiredNetwork"?是"NETWORK_STATE_ANY"吗?
-
文档说从onRunTask返回的内容,我可以返回任何值"RESULT_FAILURE","RESULT_RESCHEDULE","RESULT_SUCCESS"(信息在这里(。似乎失败和成功选项都会做同样的事情 - 从队列中删除任务。是真的吗?如果是这样,它们之间到底有什么区别?它们的功能不同吗?
-
">TaskParams"是否仅用于任务的标签?我可以以某种方式使用 API 将捆绑包传递给任务吗?否则,我需要设置一个数据库来存储应该传递给任务的内容,对吗?
-
应用是否可以获取任务队列?我知道使用 adb 是可能的,但也可以使用 API 吗?
-
他们说(在这里(每个任务都有长达 3 分钟的唤醒锁。如果任务需要更多,应该怎么做?它应该为自己获得另一个唤醒锁吗?API 是否会警告唤醒锁已释放?以下是文档的内容:
调度程序将为您的服务保存一个 PowerManager.WakeLock, 但是,在执行三分钟后,如果您的任务尚未返回 它将被视为已超时,并且唤醒锁将是 释放。此时重新安排任务将不起作用。如果 您怀疑您的任务会运行超过此时间,您应该开始您的 显式拥有服务或使用其他机制;此接口是 用于相对快速的网络操作。
-
他们说(在这里(每次升级/替换应用程序时都会删除所有网络任务,并且发生这种情况时会调用"onInitializeTasks",您可以再次重新安排它们。如何重新安排任务?我想我什至无法获得任务列表...
-
是否可以告诉任务更喜欢一天中的特定时间?例如,在 14:00-15:00 之间 ?
-
我注意到,如果您计划任务,然后强制停止和/或清除应用程序的数据,该任务仍将运行。如何避免此行为?
Jacktech24 做得很好,但如果有任何挥之不去的问题,我也会尝试。
-
似乎它需要使用Google Play服务(这里((除了使用Lollipop版本的Android时,它将使用普通的JobScheduler(。如果 Google Play 服务不可用,我该怎么办?
如果 Google Play 服务不可用,您将无法使用此 API。相反,Google Play服务客户端库旨在请求用户下载并安装Google Play服务,如果它检测到它丢失,但我不相信GcmNetworkManager会这样做。
-
任务的默认行为是什么,如果我不使用"setRequiredNetwork"?是"NETWORK_STATE_ANY"吗?
javadoc描述了哪个是默认值。
-
文档说从onRunTask返回的内容,我可以返回任何值"RESULT_FAILURE","RESULT_RESCHEDULE","RESULT_SUCCESS"(信息在这里(。似乎失败和成功选项都会做同样的事情 - 从队列中删除任务。是真的吗?如果是这样,它们之间到底有什么区别?它们的功能是否不同?
这两者之间的唯一区别是,在 adb shell dumpsys 中,它将显示您返回的内容,因此您可以使用它来解决问题。另一个原因是,如果任务失败,要求客户端返回"成功"是很奇怪的。
-
"TaskParams"是否仅用于任务的标签?我可以以某种方式使用 API 将捆绑包传递给任务吗?否则,我需要设置一个数据库来存储应该传递给任务的内容,对吗?
在下一版本的 GmsCore 中,应该支持向任务添加捆绑包的功能。
-
应用是否可以获取任务队列?我知道使用 adb 是可能的,但也可以使用 API 吗?
不,这是不可能的。相反,您应该在需要时执行取消,如果任务不存在,它将是无操作。同样,应将任务安排在代码中查询任务列表的位置。使用 setUpdateCurrent=false 来确保它不会更新预先存在的任务。AlarmManager 的工作方式与此类似,因为无论警报是否已设置,您都可以设置警报 - API 旨在遵循此设置。
-
他们说(在这里(每个任务都有长达 3 分钟的唤醒锁。如果任务需要更多,应该怎么做?它应该为自己获得另一个唤醒锁吗?API 是否会警告唤醒锁已释放?以下是文档的内容:*
是的,该应用程序应该获得自己的唤醒锁,一切都会好起来的。调度程序在 3 分钟后释放唤醒锁的原因是,在实践中,无限唤醒锁超时只会导致很难追踪电池耗尽错误。如果你需要超过3分钟的时间,你有一个足够复杂的用例,你可以深入研究PowerManager API是如何工作的,并自己调用acquire((/release(((这真的很简单,网络管理器为你做这件事的事实比其他任何事情都更礼貌(。
-
他们说(在这里(每次升级/替换应用程序时都会删除所有网络任务,并且发生这种情况时会调用"onInitializeTasks",您可以再次重新安排它们。如何重新安排任务?我想我什至无法获得任务列表...*
您可以按照最初计划任务的方式重新安排任务。无论您使用什么函数来调度它们,都可以从 GcmTaskService#onInitializeTasks 调用该函数。这样做是为了避免跨应用逻辑更改的延迟任务。考虑开发人员更改其任务时间表并开始使用其他标记的情况。在检测到升级后,他们需要调用 cancel(old_tag((他们必须添加更多代码才能执行此操作(,这意味着即使在新代码中,他们也需要引用旧的(未使用的(标记。这意味着标记是一个稳定的标识符,不应在应用升级期间更改 - 这不应该是此 API 的要求。
-
是否可以告诉任务更喜欢一天中的特定时间?例如,在 14:00-15:00 之间 ?*
否,这种类型的后台调度会导致在大量设备中放牧时出现各种问题。 即,如果 1 台设备在 15:00 运行作业,这可能没问题。但是,如果 1x10e6 突然出现,您的服务器出现了严重问题。
-
我注意到,如果您计划任务,然后强制停止和/或清除应用程序的数据,该任务仍将运行。如何避免此行为?
不幸的是,你不能,但这不是故意的,应该改变 - 在用户明确停止应用后,应用应该无法运行。
你可以在这里找到大多数问题的答案。
https://github.com/jacktech24/gcmnetworkmanager-android-example/blob/master/README.md
对于那里没有回答的答案
7:当唤醒锁被删除时,你不会收到通知,正如他们在文档中所说的那样,这个API只适用于短任务,如果你有更长的任务,编写你自己的实现
9:不,你现在不能,API不允许它
10:那是因为Google Play服务正在照顾它,没有办法绕过它。您必须在服务中检测应用程序是否已设置(我希望这是您的问题(,例如。创建配置等,并最终在调用其中一个任务时取消所有任务。