我需要在后台实现将一些数据发布到Web服务器。只是为了澄清,“在后台”,我并不是指使用类似AsyncTask
或ASIHTTPRequest
的{{{{{{{{{{{{{ 1}}方法。我需要维护一个数据队列,当用户在应用程序中工作时,线程可以异步地开始处理和发布到Web服务。
我正在寻找一些设计这样的队列的帮助,特别是在一些边缘情况下,例如用户接收呼叫,在帖子发生时退出应用程序,用户离开应用程序转到另一个一个帖子正在发生等。你会如何处理这些案件?有没有可以推荐的源代码呢?
谢谢,
的Teja。
答案 0 :(得分:3)
我最近开始在自己的工作中使用NSOperationQueue
来控制后台网络请求。 NSOperation
处理在后台线程上异步运行任务(如网络操作)所需的大部分样板代码(如果UI更新需要,则为前台)。
它还允许跨队列的依赖;例如,我在我的应用程序中使用了两个队列:
第一个在后台安排图像下载,最大并发数为2。每个图像下载都有一个相应的完成处理程序(作为NSBlockOperation
),它依赖于图像下载完成。这些操作位于[NSOperationQueue mainQueue]
,它在主线程上运行,允许它们更新UI(特别是相应的UIImageView
)。
请注意,NSOperation
和NSOperationQueue
不仅适用于网络请求,而是适用于可分为原子任务和同时调度的任何操作。
Here是Apple关于此主题的介绍文档。
答案 1 :(得分:2)
自己实现了类似的功能后,我建议使用服务而不是线程来进行网络调用。这样即使你的活动被杀,你也确定你的网络电话会被执行。
然后为了实现队列,我建议你看一下IntentService(http://developer.android.com/reference/android/app/IntentService.html)
来自文档:
IntentService是处理异步的Services的基类 请求(表示为Intents)。客户端发送请求 通过startService(Intent)调用;该服务根据需要启动, 使用工作线程依次处理每个Intent,并自行停止 当它用完了。
此“工作队列处理器”模式通常用于卸载任务 来自应用程序的主线程。 IntentService类存在于 简化这种模式并处理机制。要使用它, 扩展IntentService并实现onHandleIntent(Intent)。 IntentService将接收Intents,启动一个工作线程,并且 酌情停止服务。
所有请求都在一个工作线程上处理 - 它们可以作为 只要有必要(并且不会阻止应用程序的主循环), 但一次只能处理一个请求。
如果您的应用程序足够简单,您可以使用sendBroadCast()在您的活动和IntentService之间共享信息和通知
答案 2 :(得分:0)
创建一个封装线程的单例:
在对象的初始化中:
[NSThread detachNewThreadSelector:@selector(mainPosterThread) toTarget:self withObject:nil];
- (void)mainDownloaderThread
{
if( [NSThread respondsToSelector:@selector(setThreadPriority:)] )
{
[NSThread setThreadPriority:0.1];
}
NSString *urlToDownload = nil;
while(shouldRun)
{
// Take next data to post in a queue (lastObject of a NSArray for example)
if( nextDataToPost )
{
// Post
}
else
{
// Sleep for some time.
}
}
}
当应用程序在多任务支持的设备上进入后台/前台时,您还可以拥有停止/启动线程的方法。如果不支持多任务处理,请在停止时(如果不是太长)将后期数据保存在队列中,并在开始时将其恢复。最大的挑战是管理能够在应用程序结束时取消当前上传。
答案 3 :(得分:0)
这是我在我编写的每个新应用程序中一直在完善的问题。基本上我想要的是异步的网络功能,这是我使用本机功能编写的。如果您有兴趣,我很乐意向您展示一些代码。
首先,我建议您使用委托在主线程异步而不是同步进行所有网络调用。这种方式序列化/同步/并发不是问题。由于类是网络代理,我只发送一个类到新连接有新委托实例的位置。
[[NSURLConnection alloc] initWithRequest:request delegate:del] autorelease];
e.g.
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data