一般来说,如果不进行后台申请,在iOS系统上,当应用退到后台后,只有5s的时间去执行代码,之后将进入挂起状态。只有像音频播放、定位、newsstand、VoIP等功能才能持续在后台运行。但是开发其它应用是我们可以通过申请后台,来获得3分钟的后台执行代码时间(iOS7以前是10分钟)。
程序有一下几种状态。
- Not running 未运行 程序没启动
- Inactive 未激活 程序在前台运行,不过没有接收到事件。在没有事件处理情况下程序通常停留在这个状态
- Active 激活 程序在前台运行而且接收到了事件。这也是前台的一个正常的模式
- Backgroud 后台 程序在后台而且能执行代码,大多数程序进入这个状态后会在在这个状态上停留一会。时间到之后会进入挂起状态
- Suspended 挂起 程序不执行代码。系统会自动把程序变成这个状态而且不会发出通知。当 挂起时,程序还是停留在内存中的,当系统内存低时,系统就把挂起的程序清除掉,为前台程序提供更多的内存。
我们可以通过下面的code,让程序一直保持在“Backgroud”状态。
class AppDelegate: UIResponder, UIApplicationDelegate {
var bgTask : UIBackgroundTaskIdentifier?
var timer : Timer?
var remaining : Int = 0
func applicationDidEnterBackground(_ application: UIApplication) {
comeToBackGround(name: "A")
}
/* beginBackgroundTaskWithExpirationHandler 方法只能让App在background状态下存在30s,
然后系统会强制挂起app,或者开发者自己调用 endBackgroundTask 方法 ,
所以我们要让app做一些任务比如播放音乐,定位...才能持续申请background持续时间 */
func comeToBackGround(name:String){
print("ktkt: Start!!!")
let app = UIApplication.shared
self.bgTask = app.beginBackgroundTask(withName: name, expirationHandler: {
print("ktkt:Reamining_ 0 :\(self.remaining)")
if let bgTsk = self.bgTask{//大概30s,掉用一次
AudioPlayTool.shared.playAudio(with:“1秒的无声音乐”)
app.endBackgroundTask(bgTsk)
self.comeToBackGround(name: "BGTask:\(self.remaining)")
}
})
if self.timer != nil {
self.timer?.invalidate()
self.timer = nil
}
self.timer = Timer.scheduledTimer(timeInterval:1, target: self, selector: #selector(applyForMoreTime), userInfo: nil, repeats: true)
self.timer?.fire()
}
@objc func applyForMoreTime(){
let app = UIApplication.shared
let state = app.applicationState
print("ktkt:Reamining_ 1 :\(remaining) | \(state.rawValue)")
remaining += 1
if remaining >= 3 * 60 {//其实可以持续很久,这里写了3min
exit(0) //kill app
}
}
}