一般來說,如果不進行后臺申請,在iOS系統上,當應用退到后臺后,只有5s的時間去執行代碼,之后將進入掛起狀態。只有像音頻播放、定位、newsstand、VoIP等功能才能持續在后臺運行。但是開發其它應用是我們可以通過申請后臺,來獲得3分鐘的后臺執行代碼時間(iOS7以前是10分鐘)。
最近,我搜集了一些關于iOS程序后臺運行的方法,在此整理一下。本篇文章,我會貼出,后臺運行3分鐘和無限后臺的方法。
在此之前,?你得了解iOS應用程序的生命周期:
Not running 未運行
程序沒啟動
Inactive 未激活
程序在前臺運行,不過沒有接收到事件。在沒有事件處理情況下程序通常停留在這個狀態
Active 激活
程序在前臺運行而且接收到了事件。這也是前臺的一個正常的模式
Backgroud 后臺
程序在后臺而且能執行代碼,大多數程序進入這個狀態后會在在這個狀態上停留一會。時間到之后會進入掛起狀態(Suspended)。有的程序經過特殊的請求后可以長期處于Backgroud狀態
Suspended 掛起
程序在后臺不能執行代碼。系統會自動把程序變成這個狀態而且不會發出通知。當掛起時,程序還是停留在內存中的,當系統內存低時,系統就把掛起的程序清除掉,為前臺程序提供更多的內存。
iOS應用程序生命周期(前后臺切換,應用的各種狀態)詳解
一般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
好了,就這些,不懂的私信我!如用錯誤,請指教!