在iOS系统,App的前台运行和后台运行,行为是不同的,iOS操作系统对后台运行做了诸多限制,为了能够让系统运行更流程和更省电。
App的状态如下图:
对于后台运行,首先需要确定设备是否支持多任务,在iOS4.0 之前是否没办法做到多任务的,不过现在iOS4.0的设备已经很少了。
- UIDevice* device = [UIDevice currentDevice];
- BOOL backgroundSupported = NO;
- if ([device respondsToSelector:@selector(isMultitaskingSupported)])
- backgroundSupported = device.multitaskingSupported;
有三种方式可以在App切后台后,获得后台执行,第一种是执行有限时间的后台任务,第二种通过本地通知执行定时任务,第三种执行长运行后台任务(系统开发的音乐播放等)
第一种,使用beginBackgroundTaskWithExpirationHandler:在
applicationDidEnterBackground里调用
- - (void)applicationDidEnterBackground:(UIApplication *)application
- {
- // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
- // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
- 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.
- // your code
- NSLog(@" %f",application.backgroundTimeRemaining);
- [application endBackgroundTask:bgTask];
- bgTask = UIBackgroundTaskInvalid;
- });
- }
- - (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];
- 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];
- }
- }
第三种调用系统指定的后台运行任务,有一下这些,例如GPS 音乐等
Apps that play audible content to the user while in the background, such as a music player app
Apps that record audio content while in the background.
Apps that keep users informed of their location at all times, such as a navigation app
Apps that support Voice over Internet Protocol (VoIP)
Apps that need to download and process new content regularly
Apps that receive regular updates from external accessories
在项目中,我用的是第一种,大致就是每次在app在切后台,发送一些网络请求去server,遇到个问题,就是如果采用异步方式发送请求时,未等App收到回复,程序已切到后台,所以把其改成同步请求,如:
- NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.baidu.com"]];
- NSError *error;
- NSURLResponse *response;
- NSData *data= [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];