iOS让App后台运行
字数1282 阅读1408 评论12 喜欢68
Collection/Bookmark/Share for width under 768px
一般来说,如果不进行后台申请,在iOS系统上,当应用退到后台后,只有5s的时间去执行代码,之后将进入挂起状态。只有像音频播放、定位、newsstand、VoIP等功能才能持续在后台运行。但是开发其它应用是我们可以通过申请后台,来获得3分钟的后台执行代码时间(iOS7以前是10分钟)。
最近,我搜集了一些关于iOS程序后台运行的方法,在此整理一下。本篇文章,我会贴出,后台运行3分钟和无限后台的方法。
在此之前,你得了解iOS应用程序的生命周期:
Not running 未运行 程序没启动
Inactive 未激活 程序在前台运行,不过没有接收到事件。在没有事件处理情况下程序通常停留在这个状态
Active 激活 程序在前台运行而且接收到了事件。这也是前台的一个正常的模式
Backgroud 后台 程序在后台而且能执行代码,大多数程序进入这个状态后会在在这个状态上停留一会。时间到之后会进入挂起状态(Suspended)。有的程序经过特殊的请求后可以长期处于Backgroud状态
Suspended 挂起 程序在后台不能执行代码。系统会自动把程序变成这个状态而且不会发出通知。当挂起时,程序还是停留在内存中的,当系统内存低时,系统就把挂起的程序清除掉,为前台程序提供更多的内存。
一般App进入后台之后,超过了后台运行时间,便进入了挂起状态,无法执行代码,但是内存并没有清除。
主要用到2个方法:
beginBackgroundTaskWithExpirationHandler://申请后台,该方法只有在App处于激活时调用才有效。
endBackgroundTask://注销后台
后台执行3分钟方法:
#import "AppDelegate.h"
@interface AppDelegate (){
NSInteger count;
}
@property(strong, nonatomic)NSTimer *mTimer;
@property(assign, nonatomic)UIBackgroundTaskIdentifier backIden;
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
count=0;
return YES;
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
_mTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(countAction) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:_mTimer forMode:NSRunLoopCommonModes];
[self beginTask];
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
NSLog(@"进入前台");
[self endBack];
}
//计时
-(void)countAction{
NSLog(@"%li",count++);
}
//申请后台
-(void)beginTask
{
NSLog(@"begin=============");
_backIden = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
//在时间到之前会进入这个block,一般是iOS7及以上是3分钟。按照规范,在这里要手动结束后台,你不写也是会结束的(据说会crash)
NSLog(@"将要挂起=============");
[self endBack];
}];
}
//注销后台
-(void)endBack
{
NSLog(@"end=============");
[[UIApplication sharedApplication] endBackgroundTask:_backIden];
_backIden = UIBackgroundTaskInvalid;
}
@end
无限后台的方法,慎用!因为这个需要申请后台播放音频的权限。如果你的应用不是相关应用,AppStore审核可能不会通过。
好了,看方法!
先在info.plist文件里添加如此一条记录:
AppDelegate.m文件
#import "AppDelegate.h"
@interface AppDelegate (){
NSInteger count;
}
@property(strong, nonatomic)NSTimer *mTimer;
@property(assign, nonatomic)UIBackgroundTaskIdentifier backIden;
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
count=0;
return YES;
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
_mTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(countAction) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:_mTimer forMode:NSRunLoopCommonModes];
[self beginTask];
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
NSLog(@"进入前台");
[self endBack];
}
//计时
-(void)countAction{
NSLog(@"%li",count++);
}
//申请后台
-(void)beginTask
{
NSLog(@"begin=============");
_backIden = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
NSLog(@"将要挂起=============");
[self endBack];
}];
}
//注销后台
-(void)endBack
{
NSLog(@"end=============");
[[UIApplication sharedApplication] endBackgroundTask:_backIden];
_backIden = UIBackgroundTaskInvalid;
}
@end
ViewController.m文件
#import "ViewController.h"
#import <AVFoundation/AVFoundation.h>
@interface ViewController ()
@property(strong, nonatomic)AVAudioPlayer *mPlayer;
@property(assign, nonatomic)CGFloat mCount;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
_mCount = 0;
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:10 target:self selector:@selector(countTime) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
}
-(void)countTime{
_mCount+=10;
NSLog(@"%f",_mCount);
if ([[UIApplication sharedApplication] backgroundTimeRemaining] < 60.) {//当剩余时间小于60时,开如播放音乐,并用这个假前台状态再次申请后台
NSLog(@"播放%@",[NSThread currentThread]);
[self playMusic];
//申请后台
[[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
NSLog(@"我要挂起了");
}];
}
}
-(void)playMusic{
//1.音频文件的url路径,实际开发中,用无声音乐
NSURL *url=[[NSBundle mainBundle]URLForResource:@"欢沁.mp3" withExtension:Nil];
//2.创建播放器(注意:一个AVAudioPlayer只能播放一个url)
_mPlayer=[[AVAudioPlayer alloc]initWithContentsOfURL:url error:Nil];
//3.缓冲
[_mPlayer prepareToPlay];
//4.播放
[_mPlayer play];
}
@end