iOS 後臺運行

文一

我從蘋果文檔中得知,通常的應用在進入後臺的時候能夠獲取必定時間來運行相關任務,也就是說能夠在後臺運行一小段時間。html


還有三種類型的能夠運行在後以,
1.音樂
2.location
ios

3.voip網絡

文二

在IOS後臺執行是本文要介紹的內容,大多數應用程序進入後臺狀態不久後轉入暫停狀態。在這種狀態下,應用程序不執行任何代碼,並有可能在任意時候從內存中刪除。應用程序提供特定的服務,用戶能夠請求後臺執行時間,以提供這些服務。session

判斷是否支持多線程多線程


  1. UIDevice* device = [UIDevice currentDevice];app

  2. BOOL backgroundSupported = NO;框架

  3. if ([device respondsToSelector:@selector(isMultitaskingSupported)])socket

  4. backgroundSupported = device.multitaskingSupported;async

聲明你須要的後臺任務ide

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://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後臺執行是本文要介紹的內容,大多數應用程序進入後臺狀態不久後轉入暫停狀態。在這種狀態下,應用程序不執行任何代碼,並有可能在任意時候從內存中刪除。應用程序提供特定的服務,用戶能夠請求後臺執行時間,以提供這些服務。

判斷是否支持多線程


  1. UIDevice* device = [UIDevice currentDevice];

  2. BOOL backgroundSupported = NO;

  3. if ([device respondsToSelector:@selector(isMultitaskingSupported)])

  4. backgroundSupported = device.multitaskingSupported;

聲明你須要的後臺任務

Info.plist中添加UIBackgroundModes鍵值,它包含一個或多個string的值,包括

audio:在後臺提供聲音播放功能,包括音頻流和播放視頻時的聲音

location:在後臺能夠保持用戶的位置信息

voip:在後臺使用VOIP功能

前面的每一個value讓系統知道你的應用程序應該在適當的時候被喚醒。例如,一個應用程序,開始播放音樂,而後移動到後臺仍然須要執行時間,以填補音頻輸出緩衝區。添加audio鍵用來告訴系統框架,須要繼續播放音頻,而且能夠在合適的時間間隔下回調應用程序;若是應用程序不包括此項,任何音頻播放在移到後臺後將中止運行。

除了添加鍵值的方法,IOS還提供了兩種途徑使應用程序在後臺工做:

Task completion—應用程序能夠向系統申請額外的時間去完成給定的任務

Local notifications—應用程序能夠預先安排時間執行local notifications 傳遞

實現長時間的後臺任務

應用程序能夠請求在後臺運行以實現特殊的服務。這些應用程序並不連續的運行,可是會被系統框架在合適的時間喚醒,以實現這些服務

一、 追蹤用戶位置:略

二、在後臺播放音頻:

添加UIBackgroundModes中audio值,註冊後臺音頻應用。這個值使得應用程序能夠在後臺使用可聽的背景,如音樂播放或者音頻流應用。對於支持音頻和視頻功能的應用程序也能夠添加該值以保證能夠繼續持續的運行流。

當audio值設置後,當你的應用程序進入後臺後,系統的多媒體框架會自動阻止它被掛斷,可是,若是應用程序中止播放音頻或者視頻,系統將掛斷應用程序。

當你的應用程序在後臺時,你能夠執行任意的系統音頻框架去初始化後臺音頻。你的應用程序在後臺時應該限制自身,使其執行與工做相關的代碼,不能執行任何與播放內容無關的任務

因爲有多個應用程序支持音頻,前臺的應用程序始終容許播放音頻,後臺的應用程序也被容許播放一些音頻內容,這取決於audio session object的設置。應用程序應該始終設置它們的audio session object,並當心的處理其餘類型的音頻相關notifications和中斷。詳見audio session programming guide。

三、實現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

接口

設置


  1. NSInputStream 和NSOutputStream

對於 Cocoa streams, 使用 setProperty:forKey: 方法添加


  1. NSStreamNetworkServiceType

  2. 屬性給

  3. stream.

  4. 改屬性的值設爲

  5. NSStreamNetworkServiceTypeVoIP.

  6. NSURLRequest

對於 URL loading system, 使用 setNetworkServiceType:


  1. method of your NSMutableURLRequest object to set the network service

  2. type of the request. The service type should be set to

  3. NSURLNetworkServiceTypeVoIP.

CFReadStreamRef和CFWriteStreamRef


  1. For Core Foundation streams, use the CFReadStreamSetProperty or

  2. CFWriteStreamSetProperty function to add the kCFStreamNetwork-

  3. ServiceType property to the stream. The value for this property should be

  4. 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上或者從網絡下載一個重要的文件。有兩種方式來初始化這樣的任務:

一、將長時間運行的重要任務用beginBackgroundTaskWithExpirationHandler:和endBackgroundTask:包裝。這樣就在程序忽然切入後臺的時候保護了這些任務不被中斷。

二、當你的應用程序委託applicationDidEnterBackground:方法被調用時再啓動任務

中的兩個方法必須是一一對應的,endBackgroundTask:方法告訴系統任務已經完成,程序在此時能夠被終止。因爲應用程序只有有限的時間去完成後臺任務,你必須在超時或系統將要終止這個程序以前調用這個方法。爲了不被終止,你也能夠在一個任務開始的時候提供一個expiration handler和endBackgroundTask:方法。(能夠查看backgroundTimeRemaining屬性來肯定還剩多少時間)。

一個程序能夠同時提供多個任務,每當你啓動一個任務的時候,beginBackgroundTaskWithExpirationHandler:方法將返回一個獨一無二的handler去識別這個任務。你必須在endBackgroundTask:方法中傳遞相同的handler來終止該任務。


  1. Listing 4-2 Starting a background task at quit time

  2. - (void)applicationDidEnterBackground:(UIApplication *)application

  3. {

  4. UIApplication* app = [UIApplication sharedApplication];

  5. bgTask = [app beginBackgroundTaskWithExpirationHandler:^{

  6. [app endBackgroundTask:bgTask];

  7. bgTask = UIBackgroundTaskInvalid;

  8. }];

  9. // Start the long-running task and return immediately.

  10. dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,

  11. 0), ^{

  12. // Do the work associated with the task.

  13. [app endBackgroundTask:bgTask];

  14. bgTask = UIBackgroundTaskInvalid;

  15. });

  16. }

上述例子中,bgTask變量是一個類的成員變量,存儲着指向該後臺任務標示的指針。

在expriation handler中,能夠添加關閉任務所需的代碼。儘管如此,加入的代碼不能執行太長的時間,當expriation handler被調用的時候,該程序已經很是接近被關閉,因此只有極短的時間來清除狀態信息並終止任務。

安排Local Notification的傳遞

UILocalNotification類提供了一種方法來傳遞local notifications。和push notifications須要設置remote server不一樣,local notifications 在程序中安排並在當前的設備上執行。知足以下條件可使用該能力:

一、一個基於時間的程序,能夠在未來特定的時間讓程序post 一個alert,好比鬧鐘

二、一個在後臺運行的程序,post 一個local notification去引發用戶的注意

爲了安排local notification 的傳遞,須要建立一個UILocalNotification的實例,並設置它,使用UIApplication類方法來安排它。Local notification對象包含了所要傳遞的類型(sound,alert,或者badge)和時間什麼時候呈現)。UIApplication類方法提供選項去肯定是當即傳遞仍是在指定的時間傳遞。


  1. Listing 4-3 Scheduling an alarm notification

  2. - (void)scheduleAlarmForDate:(NSDate*)theDate

  3. {

  4. UIApplication* app = [UIApplication sharedApplication];

  5. NSArray* oldNotifications = [app scheduledLocalNotifications];

  6. // Clear out the old notification before scheduling a new one.

  7. if ([oldNotifications count] > 0)

  8. [app cancelAllLocalNotifications];

  9. // Create a new notification.

  10. UILocalNotification* alarm = [[[UILocalNotification alloc] init] autorelease];

  11. if (alarm)

  12. {

  13. alarm.fireDate = theDate;

  14. alarm.timeZone = [NSTimeZone defaultTimeZone];

  15. alarm.repeatInterval = 0;

  16. alarm.soundName = @"alarmsound.caf";

  17. alarm.alertBody = @"Time to wake up!";

  18. [app scheduleLocalNotification:alarm];

  19. }

  20. }

(能夠最多包含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)來觸發處理,若是在處理代碼中加上下面這條語句則必然會致使異常退出:

 

能夠經過一種方法來請求更多後臺時間來避免此問題。假設接收通知而觸發的處理方法是applicationDidEnterBackground:

 

 

 

  1. -(void)applicationDidEnterBackground{

  2. NSLog(@"%@",NSStringFromSelector(_cmd));

  3. //獲得當前應用程序的UIApplication對象

  4. UIApplication *app = [UIApplication sharedApplication];

  5. //一個後臺任務標識符

  6. UIBackgroundTaskIdentifier taskID;

  7. taskID = [app beginBackgroundTaskWithExpirationHandler:^{

  8. //若是系統以爲咱們仍是運行了過久,將執行這個程序塊,並中止運行應用程序

  9. [app endBackgroundTask:taskID];

  10. }];

  11. //UIBackgroundTaskInvalid表示系統沒有爲咱們提供額外的時候

  12. if (taskID == UIBackgroundTaskInvalid) {

  13. NSLog(@"Failed to start background task!");

  14. return;

  15. }

  16. NSLog(@"Starting background task with %f seconds remaining", app.backgroundTimeRemaining);

  17. [NSThread sleepForTimeInterval:10];

  18. NSLog(@"Finishing background task with %f seconds remaining",app.backgroundTimeRemaining);

  19. //告訴系統咱們完成了

  20. [app endBackgroundTask:taskID];

  21. }

 

文八:

IOS開發之----詳解在IOS後臺執行