文一
我從蘋果文檔中得知,一般的應用在進入後臺的時候可以獲取一定時間來運行相關任務,也就是說可以在後臺運行一小段時間。
還有三種類型的可以運行在後以,
1.音樂
2.location
3.voip
文二
在IOS後臺執行是本文要介紹的內容,大多數應用程序進入後臺狀態不久後轉入暫停狀態。在這種狀態下,應用程序不執行任何代碼,並有可能在任意時候從內存中刪除。應用程序提供特定的服務,用戶可以請求後臺執行時間,以提供這些服務。
判斷是否支持多線程
- UIDevice* device = [UIDevice currentDevice];
- BOOL backgroundSupported = NO;
- if ([device respondsToSelector:@selector(isMultitaskingSupported)])
- backgroundSupported = device.multitaskingSupported;
聲明你需要的後臺任務
Info.plist中添加UIBackgroundModes鍵值,它包含一個或多個string的值,包括
audio:在後臺提供聲音播放功能,包括音頻流和播放視頻時的聲音
location:在後臺可以保持用戶的位置信息
voip:在後臺使用VOIP功能
前面的每個value讓系統知道你的應用程序應該在適當的時候被喚醒。例如,一個應用程序,開始播放音樂,然後移動到後臺仍然需要執行時間,以填補音頻輸出緩衝區。添加audio鍵用來告訴系統框架,需要繼續播放音頻,並且可以在合適的時間間隔下回調應用程序;如果應用程序不包括此項,任何音頻播放在移到後臺後將停止運行。
除了添加鍵值的方法,IOS還提供了兩種途徑使應用程序在後臺工作:
Task completion—應用程序可以向系統申請額外的時間去完成給定的任務
Local notifications—應用程序可以預先安排時間執行local notifications 傳遞
文三
如何讓程序後臺播放音樂
http://developer.apple.com/library/ios/#qa/qa1668/_index.html
文四
如果你的應用程序需要後臺運行,可以使用以下方法:
1。應用程序可以請求一個有限的時間內完成一些重要任務。
2。應用程序可以聲明爲支持特定服務需要定期後臺執行時間。
3。應用程序可以使用本地生成用戶在指定的時間的警報,應用程序正在運行與否的通知。
原文地址:http://blog.csdn.net/diyagoanyhacker/article/details/7071055
作者:禚來強
聲明:此文一部分來自網絡,一部分來自官方文檔(翻譯),還有一部分是作者的總結
文五
後臺運行被第一次提到
http://developer.apple.com/library/ios/#releasenotes/General/WhatsNewIniPhoneOS/Articles/iPhoneOS4.html#//apple_ref/doc/uid/TP40009559-SW1
文六
後臺運行官方文檔
http://developer.apple.com/library/ios/#documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/ManagingYourApplicationsFlow/ManagingYourApplicationsFlow.html#//apple_ref/doc/uid/TP40007072-CH4-SW3
在IOS後臺執行是本文要介紹的內容,大多數應用程序進入後臺狀態不久後轉入暫停狀態。在這種狀態下,應用程序不執行任何代碼,並有可能在任意時候從內存中刪除。應用程序提供特定的服務,用戶可以請求後臺執行時間,以提供這些服務。
判斷是否支持多線程
- UIDevice* device = [UIDevice currentDevice];
- BOOL backgroundSupported = NO;
- if ([device respondsToSelector:@selector(isMultitaskingSupported)])
- backgroundSupported = device.multitaskingSupported;
聲明你需要的後臺任務
Info.plist中添加UIBackgroundModes鍵值,它包含一個或多個string的值,包括
audio:在後臺提供聲音播放功能,包括音頻流和播放視頻時的聲音
location:在後臺可以保持用戶的位置信息
voip:在後臺使用VOIP功能
前面的每個value讓系統知道你的應用程序應該在適當的時候被喚醒。例如,一個應用程序,開始播放音樂,然後移動到後臺仍然需要執行時間,以填補音頻輸出緩衝區。添加audio鍵用來告訴系統框架,需要繼續播放音頻,並且可以在合適的時間間隔下回調應用程序;如果應用程序不包括此項,任何音頻播放在移到後臺後將停止運行。
除了添加鍵值的方法,IOS還提供了兩種途徑使應用程序在後臺工作:
Task completion—應用程序可以向系統申請額外的時間去完成給定的任務
Local notifications—應用程序可以預先安排時間執行local notifications 傳遞
實現長時間的後臺任務
應用程序可以請求在後臺運行以實現特殊的服務。這些應用程序並不連續的運行,但是會被系統框架在合適的時間喚醒,以實現這些服務
1、 追蹤用戶位置:略
2、在後臺播放音頻:
添加UIBackgroundModes中audio值,註冊後臺音頻應用。這個值使得應用程序可以在後臺使用可聽的背景,如音樂播放或者音頻流應用。對於支持音頻和視頻功能的應用程序也可以添加該值以保證可以繼續持續的運行流。
當audio值設置後,當你的應用程序進入後臺後,系統的多媒體框架會自動阻止它被掛斷,但是,如果應用程序停止播放音頻或者視頻,系統將掛斷應用程序。
當你的應用程序在後臺時,你可以執行任意的系統音頻框架去初始化後臺音頻。你的應用程序在後臺時應該限制自身,使其執行與工作相關的代碼,不能執行任何與播放內容無關的任務
由於有多個應用程序支持音頻,前臺的應用程序始終允許播放音頻,後臺的應用程序也被允許播放一些音頻內容,這取決於audio session object的設置。應用程序應該始終設置它們的audio session object,並小心的處理其他類型的音頻相關notifications和中斷。詳見audio session programming guide。
3、實現VOIP應用:
VOIP程序需要穩定的網絡去連接和它相關的服務,這樣它才能接到來電和其他相關的數據。系統允許VOIP程序被掛斷並提供組件去監聽它們的sockets,而不是在任意時候都處於喚醒狀態。設置VOIP應用程序如下:
A、 添加UIBackgroundModes中的VOIP鍵值
B、 爲VOIP設置一個應用程序socket
C、 在移出後臺之前,調用setKeepAliveTimeout:handler:方法去建立一個定期執行的handler,你的應用程序可以運行這個handler來保持服務的連接。
D、 設置你的audio session去處理這種切換
釋義:
A、大多數VOIP應用需要設置後臺audio 應用去傳遞音頻,因此你應該設置audio 和voip兩個鍵值。
B、爲了使應用程序在後臺時保持穩定的連接,你必須tag你的主通訊socket專門應用於VOIP,tagging這個socket來告訴系統,它必須在你的應用程序中斷時接管這個socket。這個切換本身對於你的應用程序時透明的,當新的數據到達socket的時候,系統會喚醒應用程序,並將socket的控制權返回給應用程序,這樣應用程序就可以處理新來的數據。
你只需要tag用於voip服務的socket,這個socket用來接收來電或者其他相關的數據來保持你的VOIP服務的連接。根據收到的信息,這個socket要決定下一步的動作。比如一個來電,你會想彈出一個本地的通知來告知用戶;對於其他不是那麼關鍵的數據,你可能會想悄悄的處理這些數據並讓系統將應用程序重新中斷。
在IOS中,sockets是用流或者更高級的結構,設置一個VOIP的socket,你只需要在通常的設置中添加一個特殊的key來標明這個接口是用於連接VOIP服務的,下表列出了流的接口和設置:
設置流接口用於voip
接口
設置
- NSInputStream 和NSOutputStream
對於 Cocoa streams, 使用 setProperty:forKey: 方法添加
- NSStreamNetworkServiceType
- 屬性給
- stream.
- 改屬性的值設爲
- NSStreamNetworkServiceTypeVoIP.
- NSURLRequest
對於 URL loading system, 使用 setNetworkServiceType:
- method of your NSMutableURLRequest object to set the network service
- type of the request. The service type should be set to
- NSURLNetworkServiceTypeVoIP.
CFReadStreamRef和CFWriteStreamRef
- For Core Foundation streams, use the CFReadStreamSetProperty or
- CFWriteStreamSetProperty function to add the kCFStreamNetwork-
- ServiceType property to the stream. The value for this property should be
- set to kCFStreamNetworkServiceTypeVoIP.
(注意:當設置socket的時候,你需要在你的主信號通道中設置合適的service type key。當設置聲道時,不需要設置這個key)
由於,VOIP應用程序需要一直運行以確保收到來電,所以如果程序通過一個非零的exit code退出,系統將自動重啓這個應用程序(這種退出方式可以發生在內存壓力大時終止程序運行)。儘管如此,中斷應用程序會release所有的sockets,包括那個用於連接voip 服務的socket。因此,當程序運行時,它需要一直從頭創建socket。
C、 爲了防止斷連,voip程序需要定期被喚醒去檢查它的服務。爲了容易實現這個行爲,IOS通過使用(UIApplication setKeepAliveTimeout:handler:)方法建立一個特殊的句柄。你可以在applicationDidEnterBackground方法中建立該句柄。一旦建立,系統至少會在超時之前調用該句柄一次,來喚醒你的應用程序。
這個keep-alive handler在後臺執行,必須儘快的返回參數,它有最多30秒的時間來執行所需的任務,如果這段時間內句柄沒有返回,那麼系統將終止應用程序。
當你建立了handler之後,確定應用程序所需的最大超時。系統保證會在最大超時之前調用handler,但是這個時間是不確定的,所以你的handler必須在你申明的超時之前做好執行程序的準備。
D、設置audio session,詳見Audio Session Programming Guide.
在後臺完成有限長度的任務
在被終止之前的任意時間,應用程序會調用beginBackgroundTaskWithExpirationHandler:方法讓系統給出額外的時間來完成一些需要在後臺長時間執行的任務。(UIApplication的backgroundTimeRemaining屬性包含程序運行的總時間)
可以使用task completion去保證那些比較重要但是需要長時間運行的程序不會由於用戶切入後臺而突然關閉。比如,你可以用這項功能來將用戶的信息保存到disk上或者從網絡下載一個重要的文件。有兩種方式來初始化這樣的任務:
1、將長時間運行的重要任務用beginBackgroundTaskWithExpirationHandler:和endBackgroundTask:包裝。這樣就在程序突然切入後臺的時候保護了這些任務不被中斷。
2、當你的應用程序委託applicationDidEnterBackground:方法被調用時再啓動任務
中的兩個方法必須是一一對應的,endBackgroundTask:方法告訴系統任務已經完成,程序在此時可以被終止。由於應用程序只有有限的時間去完成後臺任務,你必須在超時或系統將要終止這個程序之前調用這個方法。爲了避免被終止,你也可以在一個任務開始的時候提供一個expiration handler和endBackgroundTask:方法。(可以查看backgroundTimeRemaining屬性來確定還剩多少時間)。
一個程序可以同時提供多個任務,每當你啓動一個任務的時候,beginBackgroundTaskWithExpirationHandler:方法將返回一個獨一無二的handler去識別這個任務。你必須在endBackgroundTask:方法中傳遞相同的handler來終止該任務。
- Listing 4-2 Starting a background task at quit time
- - (void)applicationDidEnterBackground:(UIApplication *)application
- {
- UIApplication* app = [UIApplication sharedApplication];
- bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
- [app 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.
- [app endBackgroundTask:bgTask];
- bgTask = UIBackgroundTaskInvalid;
- });
- }
上述例子中,bgTask變量是一個類的成員變量,存儲着指向該後臺任務標示的指針。
在expriation handler中,可以添加關閉任務所需的代碼。儘管如此,加入的代碼不能執行太長的時間,當expriation handler被調用的時候,該程序已經非常接近被關閉,所以只有極短的時間來清除狀態信息並終止任務。
安排Local Notification的傳遞
UILocalNotification類提供了一種方法來傳遞local notifications。和push notifications需要設置remote server不同,local notifications 在程序中安排並在當前的設備上執行。滿足如下條件可以使用該能力:
1、一個基於時間的程序,可以在將來特定的時間讓程序post 一個alert,比如鬧鐘
2、一個在後臺運行的程序,post 一個local notification去引起用戶的注意
爲了安排local notification 的傳遞,需要創建一個UILocalNotification的實例,並設置它,使用UIApplication類方法來安排它。Local notification對象包含了所要傳遞的類型(sound,alert,或者badge)和時間何時呈現) 。UIApplication類方法提供選項去確定是立即傳遞還是在指定的時間傳遞。
- Listing 4-3 Scheduling an alarm notification
- - (void)scheduleAlarmForDate:(NSDate*)theDate
- {
- UIApplication* app = [UIApplication sharedApplication];
- NSArray* oldNotifications = [app scheduledLocalNotifications];
- // Clear out the old notification before scheduling a new one.
- if ([oldNotifications count] > 0)
- [app cancelAllLocalNotifications];
- // Create a new notification.
- UILocalNotification* alarm = [[[UILocalNotification alloc] init] autorelease];
- if (alarm)
- {
- alarm.fireDate = theDate;
- alarm.timeZone = [NSTimeZone defaultTimeZone];
- alarm.repeatInterval = 0;
- alarm.soundName = @"alarmsound.caf";
- alarm.alertBody = @"Time to wake up!";
- [app scheduleLocalNotification:alarm];
- }
- }
(可以最多包含128個 local notifications active at any given time, any of which can be configured to repeat at a specified interval.)如果在調用該notification的時候,程序已經處於前臺,那麼application:didReceiveLocalNotification:方法將取而代之。
小結:關於詳解在IOS後臺執行的內容介紹完了,希望本文對你有所幫助!
文七
iOS不是真正的多任務系統,在用戶按下Home按鈕後,所有應用程序都會進入後臺狀態,並且大部分都會迅速進入暫停狀態,應用程序的所有工作內存都在RAM中,在暫停時它完全不執行。因此,切換回這樣的應用程序非常快。但是如果系統需要更多的內存給當前處於活動狀態的應用程序,就有可能終結暫停狀態的應用程序,它們的內存也將被釋放。
一方面,應用程序在進入後臺狀態時,需要釋放一些資源,使自身的暫停快照更小,從而減少從RAM中清除的風險,另一方面,爲了避免被終結而丟失用戶的數據,需要在用戶離開時保存他們的進度信息,這些工作,需要在5秒鐘內完成,不然會被系統認定有異常被強制退出。可能通過接收應用程序發送的通知(UIApplicationDidEnterBackgroundNotification)來觸發處理,如果在處理代碼中加上下面這條語句則必然會導致異常退出:
- [NSThread sleepForTimeInterval:10];
- -(void)applicationDidEnterBackground{
- NSLog(@"%@",NSStringFromSelector(_cmd));
- //得到當前應用程序的UIApplication對象
- UIApplication *app = [UIApplication sharedApplication];
- //一個後臺任務標識符
- UIBackgroundTaskIdentifier taskID;
- taskID = [app beginBackgroundTaskWithExpirationHandler:^{
- //如果系統覺得我們還是運行了太久,將執行這個程序塊,並停止運行應用程序
- [app endBackgroundTask:taskID];
- }];
- //UIBackgroundTaskInvalid表示系統沒有爲我們提供額外的時候
- if (taskID == UIBackgroundTaskInvalid) {
- NSLog(@"Failed to start background task!");
- return;
- }
- NSLog(@"Starting background task with %f seconds remaining", app.backgroundTimeRemaining);
- [NSThread sleepForTimeInterval:10];
- NSLog(@"Finishing background task with %f seconds remaining",app.backgroundTimeRemaining);
- //告訴系統我們完成了
- [app endBackgroundTask:taskID];
- }