我们平常使用APP时,一般人都会知道有:简单的正在使用状态;通过home键等方式离开应用,但是不关闭应用,即后台状态;以及调出后台程序管理后向上滑动将应用“杀死”,三种状态。而我们开发者则会了解得更深便于进行开发工作。还有更多更深的知识还需要在未来进行探索后总结。而接下来将对当前初级阶段对APP的生命周期所学知识进行总结。
应用程序的五种状态
1. Not running:
应用还没有启动,或者应用正在运行但是途中被系统停止。
2. Inactive:
当前应用正在前台运行,但是并不接收事件(当前或许正在执行其它代码)。一般每当应用要从一个状态切换到另一个不同的状态时,中途过渡会短暂停留在此状态。例如用户锁屏或者接到通知去响应别的事件的时候。
3. Active:
当前应用正在前台运行,并且接收事件。这是应用正在前台运行时所处的正常状态。
4. Background:
应用处在后台,并且还在执行代码。大多数将要进入Suspended状态的应用,会先短暂进入此状态。除了一些经过特殊的请求后可以长期处于此状态的应用。存在一些启动后会直接进入background状态的应用。
5. Suspended:
应用处在后台,并且已停止执行代码。系统会自动把程序变成这个状态而且不会发出通知。当挂起时,程序还是停留在内存中的,当系统内存低时,系统就把挂起的程序清除掉,为前台程序提供更多的内存。
iOS程序执行过程
可由下图做一个总览:
其中,监听系统事件的方法在AppDelegate.m文件中,里面的几个方法代理的回调分别解释为:
// 告诉代理启动基本完成程序准备开始运行
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
// 当应用程序将要入非活动状态执行,在此期间,应用程序不接收消息或事件,比如打来电话
- (void)applicationWillResignActive:(UIApplication *)application
// 当应用程序入活动状态执行,此方法跟上面那个方法相反
- (void)applicationDidBecomeActive:(UIApplication *)application
// 当程序被推送到后台的时候调用。所以要设置后台继续运行,则在这个函数里面设置即可
- (void)applicationDidEnterBackground:(UIApplication *)application
// 当程序从后台将要重新回到前台时候调用,此方法跟上面的那个方法相反
- (void)applicationWillEnterForeground:(UIApplication *)application
// 当程序将要退出是被调用,通常是用来保存数据和一些退出前的清理工作
- (void)applicationWillTerminate:(UIApplication *)application
在此添加NSLog打印进行相关操作时执行的方法
各个操作时方法执行顺序均为从上到下。
分为启动程序时:
function:-[AppDelegate application:didFinishLaunchingWithOptions:] line:25 content:-[AppDelegate application:didFinishLaunchingWithOptions:]
function:-[AppDelegate applicationDidBecomeActive:] line:52 content:-[AppDelegate applicationDidBecomeActive:]
点击home键时:
function:-[AppDelegate applicationWillResignActive:] line:33 content:-[AppDelegate applicationWillResignActive:]
function:-[AppDelegate applicationDidEnterBackground:] line:40 content:-[AppDelegate applicationDidEnterBackground:]
双击home键或点击图标再次打开程序时:
function:-[AppDelegate applicationWillEnterForeground:] line:46 content:-[AppDelegate applicationWillEnterForeground:]
function:-[AppDelegate applicationDidBecomeActive:] line:52 content:-[AppDelegate applicationDidBecomeActive:]
了解了APP运行中的几种状态和周期,我们可以对一些状况进行响应的优化和处理。
例如当出现突然来电话了等导致程序临时进入Inactive状态时,我们可以在applicationWillResignActive:
方法中:
- 停止timer 和其他周期性的任务
- 停止任何正在运行的请求
- 暂停视频的播放
- 如果是游戏那就暂停它
- 减少OpenGL ES的帧率
- 挂起任何分发的队列和不重要的操作队列(你可以继续处理网络请求或其他时间敏感的后台任务)。
当程序进入后台时:
应该实现:
- 保存用户数据或状态信息,所有没写到磁盘的文件或信息,在进入后台时,最后都写到磁盘去,因为程序可能在后台被杀死
- 释放尽可能释放的内存
在后台时,每个应用程序都应该释放最大的内存。系统会尽可能保证多的应用程序在后台运行。所以后台会为了减少程序占用的内存自动回收一些系统帮助你开辟的内存,如:
- 系统回收Core Animation的后备存储
- 去掉任何系统引用的缓存图片
- 去掉系统管理数据缓存强引用
我们也可以做一些努力:
把一些对象的强引用去掉,这样编译器就可以回收这些内存:
- 图片对象
- 你可以重新加载的 大的视频或数据文件
- 任何没用而且可以轻易创建的对象
程序终止时:
APP终止时,系统会调用applicationWillTerminate:
方法,我们可以在其中进行一些保存数据或状态或一些清理的工作。方法中的这些工作会有最多5秒的时间限制,如果超过时间还有未完成的任务,你的程序就会被终止而且从内存中清除。
而像进入后台和程序终止状态,如果还需要长时间的运行任务,可以调用 beginBackgroundTaskWithExpirationHandler
方法去请求后台运行时间和启动线程来运行长时间运行的任务。