android API 级别 15 中后台作业的选择
choices for background jobs in android API level 15
本题的大体方向
对于这个问题,请想一想网络浏览器在下载网站、图像和其他可能显示给用户的内容时需要执行的作业管理。从技术上讲,这与我面临的情况非常相似。我正在询问我有哪些选择(AsyncTask
、Service
、第 3 方库,...)来实施这样的工作管理。
详情
我正在为 android 开发一个应用程序,它需要在后台下载内容并在 运行ning 下载有更多数据可用时更新 UI。
当用户选择时,他会导航到他想要的另一个 Activity
。之前下载的数据对新的 Activity
并不重要。因此需要停止第一个下载(为新下载腾出带宽)并且需要开始新 Activity
的新下载。典型的下载时间从几秒到半分钟不等。
当用户导航回第一个 Activity
时,第一个下载不应从头开始。相反,它应该被恢复。
当当前 Activity
的下载完成,但有其他最近的下载未完成时,应继续下载,以便在用户导航到需要该数据的其他活动时,可以立即显示该数据。即使应用程序进入后台,下载也应继续,甚至定期(例如,每天一次),因此即使离线,应用程序也准备好呈现合理的最新内容。
对于 API 级别 15 的工作管理,我有哪些选择?请记住,这是关于作业管理/调度,而不是下载。下载东西很容易编程,但调度是困难的部分。
要求汇总:
- cancel/suspend 个职位(因此取消下载)
- 观察者收到有关作业进度的通知
- 部分数据必须可以访问
- 可恢复作业(阅读:可恢复下载;当然可以创建一个新作业来恢复下载)
- 当应用程序不在前台时作业可以 运行
我想过的选择
AsyncTask
我认为它不合适,因为它绑定到 Activity,所以当应用程序不在前台时将此 运行 放在后台是一个错误。
IntentService
根据 Asking an IntentService for information about its queue,不可能改变 IntentService 的队列。
Service
到目前为止,我认为我需要从头开始重写一个调度机制,或者像上面的 SO 答案所建议的那样基于 IntentService
的源代码。
Downloads shall be continued even if the app goes to background, or even regularly, say, once a day, so the app is ready to present reasonably up to date content even when offline.
这是一个不平凡的观点。这意味着您需要某种进程外调度组件,在 API 级别 15 上意味着 AlarmManager
。这会导致较新版本的 Android 出现问题,因此我建议:
全面使用 android-job
之类的包装器库,或者
在Service
中使用ThreadPoolExecutor
处理实际下载,并使用android-job
触发该服务下载需要定期下载的内容
cancel/suspend jobs (hence cancel downloads)
我的两个选项都支持取消作业。您必须为 "suspend".
发明自己的机制
observer gets notified on job progress
恕我直言,这与工作无关 management/scheduling。您最终会为此使用某种事件总线(greenrobot 的 EventBus,LocalBroadcastManager
,基于 RxJava 的总线,基于 MutableLiveData
的总线等)。
data must be accessible in parts
恕我直言,这与工作无关 management/scheduling。我不确定它是否实用,具体取决于您使用的网络。
resumable jobs (read: resumable downloads; creating a new job for resuming a download is ok, of course)
您可以使用我的两个选项创建工作。您必须为 "resumable".
创建自己的机制
jobs can run while app is not in foreground
这取决于您所说的 "foreground" 是什么意思。如果 "foreground" 是指 "has an activity that is visible to the user",那么我的两个选项都涵盖了这一点。但是,如果您使用 ThreadPoolExecutor
方法,您会希望它成为一个前台服务,就像在 Android 8.0+ 上一样,一个未绑定的后台服务(例如,一个由 AlarmManager
启动的服务) ) 只能 运行 约 1 分钟,您的总下载量可能会超过这个。如果您使用 android-job
,它应该在 Android 5.0+ 上使用 JobScheduler
,这会让您在开始遇到问题前大约 10 分钟。
本题的大体方向
对于这个问题,请想一想网络浏览器在下载网站、图像和其他可能显示给用户的内容时需要执行的作业管理。从技术上讲,这与我面临的情况非常相似。我正在询问我有哪些选择(AsyncTask
、Service
、第 3 方库,...)来实施这样的工作管理。
详情
我正在为 android 开发一个应用程序,它需要在后台下载内容并在 运行ning 下载有更多数据可用时更新 UI。
当用户选择时,他会导航到他想要的另一个 Activity
。之前下载的数据对新的 Activity
并不重要。因此需要停止第一个下载(为新下载腾出带宽)并且需要开始新 Activity
的新下载。典型的下载时间从几秒到半分钟不等。
当用户导航回第一个 Activity
时,第一个下载不应从头开始。相反,它应该被恢复。
当当前 Activity
的下载完成,但有其他最近的下载未完成时,应继续下载,以便在用户导航到需要该数据的其他活动时,可以立即显示该数据。即使应用程序进入后台,下载也应继续,甚至定期(例如,每天一次),因此即使离线,应用程序也准备好呈现合理的最新内容。
对于 API 级别 15 的工作管理,我有哪些选择?请记住,这是关于作业管理/调度,而不是下载。下载东西很容易编程,但调度是困难的部分。
要求汇总:
- cancel/suspend 个职位(因此取消下载)
- 观察者收到有关作业进度的通知
- 部分数据必须可以访问
- 可恢复作业(阅读:可恢复下载;当然可以创建一个新作业来恢复下载)
- 当应用程序不在前台时作业可以 运行
我想过的选择
AsyncTask
我认为它不合适,因为它绑定到 Activity,所以当应用程序不在前台时将此 运行 放在后台是一个错误。
IntentService
根据 Asking an IntentService for information about its queue,不可能改变 IntentService 的队列。
Service
到目前为止,我认为我需要从头开始重写一个调度机制,或者像上面的 SO 答案所建议的那样基于 IntentService
的源代码。
Downloads shall be continued even if the app goes to background, or even regularly, say, once a day, so the app is ready to present reasonably up to date content even when offline.
这是一个不平凡的观点。这意味着您需要某种进程外调度组件,在 API 级别 15 上意味着 AlarmManager
。这会导致较新版本的 Android 出现问题,因此我建议:
全面使用
android-job
之类的包装器库,或者在
Service
中使用ThreadPoolExecutor
处理实际下载,并使用android-job
触发该服务下载需要定期下载的内容
cancel/suspend jobs (hence cancel downloads)
我的两个选项都支持取消作业。您必须为 "suspend".
发明自己的机制observer gets notified on job progress
恕我直言,这与工作无关 management/scheduling。您最终会为此使用某种事件总线(greenrobot 的 EventBus,LocalBroadcastManager
,基于 RxJava 的总线,基于 MutableLiveData
的总线等)。
data must be accessible in parts
恕我直言,这与工作无关 management/scheduling。我不确定它是否实用,具体取决于您使用的网络。
resumable jobs (read: resumable downloads; creating a new job for resuming a download is ok, of course)
您可以使用我的两个选项创建工作。您必须为 "resumable".
创建自己的机制jobs can run while app is not in foreground
这取决于您所说的 "foreground" 是什么意思。如果 "foreground" 是指 "has an activity that is visible to the user",那么我的两个选项都涵盖了这一点。但是,如果您使用 ThreadPoolExecutor
方法,您会希望它成为一个前台服务,就像在 Android 8.0+ 上一样,一个未绑定的后台服务(例如,一个由 AlarmManager
启动的服务) ) 只能 运行 约 1 分钟,您的总下载量可能会超过这个。如果您使用 android-job
,它应该在 Android 5.0+ 上使用 JobScheduler
,这会让您在开始遇到问题前大约 10 分钟。