在后台IOS实现长时间运行的任务
Posted
技术标签:
【中文标题】在后台IOS实现长时间运行的任务【英文标题】:Implementing long running tasks in background IOS 【发布时间】:2013-03-07 10:28:02 【问题描述】:我一直在开发一个应用程序,用户可以使用AVFoundation
录制视频并发送到服务器,视频的最大大小为 15M,具体取决于互联网速度和类型,大约需要 1 到 5 分钟将视频传输到服务器。我正在后台线程中将录制的视频传输到服务器,以便用户可以在将视频上传到服务器时继续应用程序上的其他内容。
在阅读implementing long running tasks in backround 的 Apple 文档时,我发现只有少数几种应用程序允许在后台执行。 例如
音频 - 应用在后台向用户播放可听内容。 (此内容包括使用 AirPlay 的流式音频或视频内容。)
我的应用是否也可以在后台运行任务?或者我需要在主线程上传输视频?
【问题讨论】:
ru要在后台上传录制视频吗? 是的,这就是我正在做的事情,因为我提到我希望用户在录制视频时继续在表单上做其他事情 上传时,你的应用会在前台(执行一些其他任务)还是完全进入后台? 只有上传过程在后台进行,所有其他内容都保留在主线程上,用户可以继续在应用程序中添加详细信息 后台运行并不关心您的上传在哪个线程上运行。如果您正在谈论在用户点击主页按钮后继续上传,那么后台任务就是您想要的。如果您正在谈论在前台运行时上传,那么您的意思是在后台线程上。后台线程和后台运行是两个概念。 【参考方案1】:NSOperationQueue
是执行多线程任务的推荐方式,以避免阻塞主线程。后台线程用于您希望在应用程序处于非活动状态时执行的任务,例如 GPS 指示或音频流。
如果您的应用程序在前台运行,则根本不需要后台线程。
对于简单的任务,您可以使用块向队列添加操作:
NSOperationQueue* operationQueue = [[NSOperationQueue alloc] init];
[operationQueue addOperationWithBlock:^
// Perform long-running tasks without blocking main thread
];
有关NSOperationQueue 和how to use it 的更多信息。
上传过程将在后台继续,但您的应用程序将有资格被暂停,因此上传可能会取消。为避免这种情况,您可以在应用程序委托中添加以下代码,以告知操作系统何时可以暂停应用程序:
- (void)applicationWillResignActive:(UIApplication *)application
bgTask = [application beginBackgroundTaskWithExpirationHandler:^
// Wait until the pending operations finish
[operationQueue waitUntilAllOperationsAreFinished];
[application endBackgroundTask: bgTask];
bgTask = UIBackgroundTaskInvalid;
];
【讨论】:
这是否意味着如果用户单击电源按钮,NSOperationQueue
将继续其任务?
查看更新的答案以避免应用在不活动时被暂停。
将*
加入NSOperationQueue *
operationQueue
在这种情况下什么是 bgTask ??
@jesses.co.tt UIBackgroundTaskIdentifier
【参考方案2】:
根据您对 Dwayne 的回复,您不需要能够在后台模式下下载。相反,您需要在主线程旁边的另一个线程(后台线程)中进行下载。 GCD 是这样的:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^
// Do you download here...
);
【讨论】:
它正在将数据上传到服务器,我担心如果互联网出现故障并在一段时间后变得可用,它会恢复我的任务吗?据我了解,将不得不在 NSOperationQueue 中添加任务,如果它们处于待处理状态,那么可以恢复吗? 在失去与服务器的连接后,您的上传任务是否能够恢复取决于您使用的库是否具有此功能。如果该库不支持该功能,则将任务作为后台任务或在后台线程中运行将无济于事。 哪些库可以恢复,哪些不能?【参考方案3】:您的要求有资格在后台运行。您不需要注册 info plist 中支持的任何后台模式。您需要做的就是,当应用程序即将进入后台时,使用后台任务处理程序请求额外的时间并在该块中执行您的任务。确保在 10 分钟前停止处理程序,以免操作系统强制终止。
您可以使用以下来自 Apple 的代码。
- (void)applicationDidEnterBackground:(UIApplication *)application
bgTask = [application beginBackgroundTaskWithExpirationHandler:^
// Clean up any unfinished task business by marking where you
// stopped or ending the task outright.
[application endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
];
// Start the long-running task and return immediately.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^
// Do the work associated with the task, preferably in chunks.
[application endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
);
【讨论】:
来自 Apple Docs 不清楚,这就是我问的原因,我已经在后台线程中实现了我的上传过程并且我已经在使用多任务,我的问题是它会让我的应用程序如果它已经在后台线程中运行,会被拒绝吗?其次,我的应用程序可以处于活动或非活动状态,这无关紧要,因为它正在后台线程中执行任务。 @nsgulliver 否。Apple 不会拒绝,因为您使用后台处理程序上传。您需要做的就是确保在 10 分钟失败之前停止处理程序,否则应用程序可能会被操作系统强制终止。我已经在一些应用程序中这样做了,我对 Apple 没有任何问题。以上是关于在后台IOS实现长时间运行的任务的主要内容,如果未能解决你的问题,请参考以下文章