(11)应用在后台运行时执行最少量化的工作。系统给后台运行的应用的执行时间和给前台运行的应用相比,通常非常有限。如果应用在后台播放音频或者监测位置变化,则应用应该仅关注此任务,所有不必要的任务都应该被推迟。在后台执行时间过长的应用会被系统throttled back或者直接被kill掉。
下来我们操作一下看看:
AppDelegate.h:
///
UIBackgroundTaskIdentifier bgTask;
NSUInteger counter;
AppDelegate.m:
- (void)backgroundHandler {
NSLog(@"### -->backgroundinghandler");
UIApplication* app = [UIApplicationsharedApplication];
bgTask = [appbeginBackgroundTaskWithExpirationHandler:^{
[app endBackgroundTask:bgTask];
bgTask =UIBackgroundTaskInvalid;
}];
// Start the long-running task
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{
while (1) {
NSLog(@"counter:%d",counter++);
[[UIApplicationsharedApplication]setApplicationIconBadgeNumber:numbers++];
sleep(1);
}
});
}
- (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, called instead of applicationWillTerminate: when the user quits.
*/
printf("\n applicationDidEnterBackground \n");
//
BOOL backgroundAccepted = [[UIApplicationsharedApplication]setKeepAliveTimeout:600handler:^{
[selfbackgroundHandler];
}];
if (backgroundAccepted)
{
NSLog(@"backgrounding accepted");
}
[selfbackgroundHandler];
}
info.plist:
Required background modes字段:
App provides Voice over IP services;
OK就可以看到后台程序在运行了!
步骤:
1.在info.plist里加入UIBackgroundModes键,其值为数组,数组之一为voip字符串:
2.在程序启动的时候调用- (void)setupBackgroundHandler函数,函数体如下:
#pragma mark - VoIP
- (
void
)setupBackgroundHandler
{
if
( UIUDeviceIsBackgroundSupported() )
{
if
(
[[UIApplication sharedApplication] setKeepAliveTimeout:600 handler: ^
{
[
self
requestServerHowManyUnreadMessages];
}
]
)
{
UDLog(@
"Set Background handler successed!"
);
}
else
{
//failed
UDLog(@
"Set Background handler failed!"
);
}
}
else
{
UDLog(@
"This Deviece is not Background supported."
);
}
}
- (
void
)requestServerHowManyUnreadMessages
{
UIApplication* app = [UIApplication sharedApplication];
if
([app applicationState] == UIApplicationStateBackground)
{
NSArray
* oldNotifications = [app scheduledLocalNotifications];
if
([oldNotifications count] > 0)
[app cancelAllLocalNotifications];
UILocalNotification* alarm = [[[UILocalNotification alloc] init] autorelease];
if
(alarm)
{
alarm.fireDate = [
NSDate
dateWithTimeIntervalSinceNow:15];
alarm.timeZone = [
NSTimeZone
defaultTimeZone];
alarm.repeatInterval = 0;
alarm.soundName = UILocalNotificationDefaultSoundName;
alarm.alertBody = @
"Time to request MOA2 Server!"
;
[app scheduleLocalNotification:alarm];
}
}
else
if
([app applicationState] == UIApplicationStateActive)
{
UIAlertView *alertView = [[[UIAlertView alloc] init] autorelease];
[alertView setTitle:@
"alert"
];
[alertView setMessage:@
"Time to request MOA2 Server!"
];
[alertView addButtonWithTitle:
NSLocalizedString
(@
"cancel"
,
nil
)];
[alertView setDelegate:
nil
];
[alertView show];
}
}
|
解说:
- (BOOL)setKeepAliveTimeout:(NSTimeInterval)timeout handler:(void (^)(void))keepAliveHandler
函数功能:app每隔timeout唤醒一次。
0.要成功调用该函数,就必须在Info.plist里设UIBackgroundModes键的array值之一voip字符串.
1.timeout必须>=600
2.唤醒app的时间间隔是不精准的。
3.唤醒后只有10秒执行时间。即handler里的代码要在10秒类执行完。10秒后app再次被阻塞。
(可以用-backgroundTimeRemaining属性来返回剩余时间)
4.该函数成功调用后,在程序生命周期内有效。
该函数的效果在回到前台的状况下,依然有效。(因此可以把它当timer使.)
5.clearKeepAliveTimeout函数用来清除handler。
代码下载:http://download.csdn.net/detail/kaitiren/7930749