iOS的app生命周期还是略复杂的,主要来说分为支持多任务和不支持两种。查了查网上的资料,发现画的最精美的图就是来自上面这条blog了。因此在此主要翻译了下该文的大意,并且加上一些自己的见解。
(一)不支持多任务的app。
在iOS 4之前的系统是不支持多任务的,所以生命周期简单很多,详情先看下图:
一个应用的生命周期就是从上往下走一趟,一旦应用关闭了之后下次再打开应用就又是全新的启动状态。
1. 启动应用后首先会运行以下delegate:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
如果是由应用所绑定的url进入的应用,会继续触发以下delegate,用来给用户提供机会处理url:
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url
2. 之后应用就要真正的进入活动状态了:
- (void)applicationDidBecomeActive:(UIApplication *)application;
在进入活动状态的这个delegate里面,一般可以改变一些类似isPaused、isRunning的状态变量的值。
3. 发生中断事件(例如收到电话):
- (void)applicationWillResignActive:(UIApplication *)application;
在这个事件里我们一般需要做和becomeActive事件的操作所对应的反操作,例如将isRunning设置成NO,暂停一些线程的运行等。另外就是在这里做一些状态的储存工作,因为这里一旦用户接起电话就证明应用要终止了。
但是如果用户没有接电话的话,应用就会返回第二步重新激活活动状态。
如果用户接了电话,将会进入第四步和按了Home键结果相同。
4. 用户手动终止应用(按下Home键等),应用就会收到即将终止的通知:
- (void)applicationWillTerminate:(UIApplication *)application;
可以看到在早期版本的iOS里,没有经过resignActive步骤应用直接就收到终止通知了。然后紧接着会预留5秒(据说是5秒,我没有去考证)的时间给app做一些最后的数据保存等操作。在app操作都完成或者这个时限到了的时候,app就真正的终止了,从内存中完全消失。
(二)支持并开启了多任务支持的app
iOS 4及以后版本的系统就支持多任务了,app的生命周期相对的复杂了很多,先看图:
看上去很复杂但是实际上我们需要关注的地方也不是很复杂。
1. 程序的启动,这个和以前的iOS是完全一致的没有什么区别。启动后会进入活动状态,这也和之前没有什么区别。
2. 支持多任务模式的区别就在于在收到并进入中断或者按Home键之后都会触发resignActive事件,并且resignActive事件之后准备进入后台运行模式并触发delegate:
- (void)applicationDidEnterBackground:(UIApplication *)application;
真正进入后台模式前会首先判断下SDK的版本是不是大于4,大于4才能进入后台模式。再检测下在info.plist里面有没有禁用后台模式,具体的禁用方法就是添加一个UIApplicationExitsOnSuspend的key,如果没有关闭的话才能进入后台模式。这两个条件任意一个不满足将直接进入applicationWillTerminate过程,应用和iOS 3一样将立即终止。不然的话应用将会真正的进入后台模式。
进入真正的后台模式之后,一般的应用会处于一个挂起状态,只有app的内存会仍然存在于内存中,再次点击app的图标运行app则会恢复到退出前的状态。需要注意的是,系统内存不足的时候,或者用户在多任务界面长按app图标杀掉app进程的时候,应用会被立即终止并且我们是收不到任何delegate的,只会有一个KILL消息。所以说,在现在的iOS应用开发过程中,必须要在applicationWillResignActive事件里保存数据,applicationWillTerminate是有可能在一次生命周期中不被调用的。
然后就是应用存在后台run loop的情况,这在一些特殊条件下程序才会持续运行在后台,最常见的例子是音乐播放软件需要在后台一直运行。其次是IP网络语音服务及GPS定位服务程序可能要在后台一直监测,所以也可以运行在后台。
3. 之后就是从后台模式的恢复了,再次点击app或者由url进入app的话,会在恢复内存前触发以下delegate:
- (void)applicationWillEnterForeground:(UIApplication *)application;
然后就和之前首次进入app一样会判断以下是否需要处理url,需要处理的话会触发以下delegate:
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url;
再之后的步骤就和之前一样了,看看流程图就明白了。
(三)总结
应用一个生命周期只会调用一次didFinishLaunching,willTerminate有可能不被触发。需要做暂停和恢复操作的应用或游戏需要在becomeActive和resignActive配对操作,保存和恢复操作一般需要在enterBackground和enterForeground配对操作。其它一些细节,应该看着这图就能很轻易理解了。