APP的状态:
Not running ( 未运行 ): 程序没启动。
Inactive ( 未激活 ): 程序在前台运行,不过没有接收到事件。在没有事件处理情况下程序通常停留在这个状态。
Active ( 激活 ): 程序在前台运行而且接收到了事件。这也是前台的一个正常的模式。
Backgroud ( 后台 ): 程序在后台而且能执行代码,大多数程序进入这个状态后会在在这个状态上停留一会。时间到之后会进入挂起状态(Suspended)。有的程序经过特殊的请求后可以长期处于Backgroud状态。
Suspended ( 挂起 ): 程序在后台但是却不能执行代码。系统会自动把程序变成这个状态而且不会发出通知。
当挂起时,程序还是停留在 内存中的,当系统内存低时,系统就把挂起的程序清除掉,为前台程序提供更多的内存。
APP的DidEnterBackground/WillEnterForeground:
-
1.进入后台 ----- DidEnterBackground
当程序进入后台状态时,名为“applicationDidEnterBackground”委托方法会被调用:- (void)applicationDidEnterBackground:(UIApplication *)application { }
-
2.进入前台 ----- WillEnterForeground
当程序进入后台状态时,名为“applicationWillEnterForeground”委托方法会被调用:- (void)applicationWillEnterForeground:(UIApplication *)application { }
APP的DidBecomeActive/ResignActive:
-
1.挂起 ----- WillResignActive
当 有电话进来 或者 锁屏(拉下状态栏、双击Home键使App界面上移) 的时候,你的应用程会挂起。而在这个时候,UIApplicationDelegate委托 会收到通知,调用“applicationWillResignActive”方法,可以重写这个方法,添加 挂起之前的工作,比如:关闭网络、保存数据。- (void)applicationWillResignActive:(UIApplication*)application { }
当程序被挂起后,程序将不会在 后台运行 。
-
2.复原 ----- DidBecomeActive
当程序复原时,另一个名为“applicationDidBecomeActive”委托方法会被调用,在此你可以通过之前挂起前保存的数据 来恢复 你的应用程序:- (void)applicationDidBecomeActive:(UIApplication*)application { }
注意:应用程序在启动时,在调用了“applicationDidFinishLaunching”方法之后 同样也会 调用“applicationDidBecomeActive”方法!!!所以要确保你的代码能够分清 程序的复原与启动,避免出现逻辑上的bug。
APP的终止
当用户 按下按钮 或者 关机,程序都会被终止。当一个程序将要正常终止时,会调用“applicationWillTerminate”方法。 ⚠️:但是如果点击主按钮 强制退出,则不会调用该方法。
这个方法用于执行剩下的 清理工作~ 比如:所有的连接都能正常关闭,并在程序退出之前执行任何其他的必要的工作:
- (void)applicationWillTerminate:(UIApplication*)application { }
APP状态改变的代理方法:
// 程序 开始运行
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
return YES;
}
// 程序 挂起
- (void)applicationWillResignActive:(UIApplication *)application {
/* Sent when the application is about to move from active to inactive state. This can occur
for certain types of temporary interruptions (such as an incoming phone call or SMS message)
or when the user quits the application and it begins the transition to the background state.
*/
/* Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering
callbacks. Games should use this method to pause the game.
*/
}
// 程序 进入后台
- (void)applicationDidEnterBackground:(UIApplication *)application {
/* Use this method to release shared resources, save user data, invalidate timers, and store
enough application state information to restore your application to its current state in case
it is terminated later.
*/
/* If your application supports background execution, this method is called instead of
applicationWillTerminate: when the user quits.
*/
}
// 程序 进入前台
- (void)applicationWillEnterForeground:(UIApplication *)application {
/* Called as part of the transition from the background to the active state; here you can
undo many of the changes made on entering the background.
*/
}
// 程序 重新激活
- (void)applicationDidBecomeActive:(UIApplication *)application {
/* Restart any tasks that were paused (or not yet started) while the application was inactive.
If the application was previously in the background, optionally refresh the user interface.
*/
}
// 程序 终止
- (void)applicationWillTerminate:(UIApplication *)application {
/* Called when the application is about to terminate. Save data if appropriate.
See also applicationDidEnterBackground:.
*/
}
应用运行过程 中 状态变化 对应的“UIApplicationDelegate”方法执行:
-
首次运行:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions - (void)applicationDidBecomeActive:(UIApplication *)application
-
首次关闭(home):
- (void)applicationWillResignActive:(UIApplication *)application - (void)applicationDidEnterBackground:(UIApplication *)application
-
再次运行:
- (void)applicationWillEnterForeground:(UIApplication *)application - (void)applicationDidBecomeActive:(UIApplication *)application
-
再次关闭:
- (void)applicationWillResignActive:(UIApplication *)application - (void)applicationDidEnterBackground:(UIApplication *)application
进阶:
- “点击桌面图标,正常启动App” 或者 “杀死进程后点击推送消息,启动App” :
1.application:willFinishLaunchingWithOptions
2.application:application:didFinishLaunchingWithOptions
3.applicationDidBecomeActive
4.application:didRegisterForRemoteNotificationsWithDeviceToken // 接收、处理消息通知
- 拖下通知中心/双击Home键,使App界面上移 :
applicationWillResignActive
- 拖上通知中心/再双击Home键,使App界面恢复原位:
applicationDidBecomeActive
- 按Home键,使App 进入后台
1.applicationWillResignActive
2.applicationDidEnterBackground
- 点击App图标,使App从后台 恢复至前台
1.applicationWillEnterForeground
2.applicationDidBecomeActive
- 点击通知中心里面的远程推送,使App从后台 进入前台
1.applicationWillEnterForeground
2.application:didReceiveRemoteNotification // 接收、处理消息通知
3.applicationDidBecomeActive
- 上滑 或者 按住App图标,选择减号图标,杀死App进程(终止程序)
applicationWillTerminate
- 从APP切换到微信之类的其他应用之后,再切换回来时
1.applicationWillEnterForeground
2.application:openURL:sourceApplication // 应用间⭐️传值⭐️
3.applicationDidBecomeActive
内容来源:UIApplicationDelegate里面最常用的几个函数执行顺序小结
最后,推荐几个比较直观的图片:
The Main Run Loop ————— 主运行循环
Main Run Loop负责 处理用户相关的事件。UIApplication对象在程序启动时启动Main Run Loop,它处理事件和更新视图的界面。看Main Run Loop就知道,它是运行在程序的主线程上的。这样保证了接收到用户相关操作的事件是按顺序 处理的。
用户操作设备,相关的操作事件被系统生成并通过UIKit的指定端口分发。事件在内部排成队列,一个个的分发到Main Run Loop 去做处理。UIApplication对象是第一个接收到时间的对象,它决定事件如何被处理。触摸事件分发到主窗口,窗口再分发到对应触发 触摸事件的View。其他的事件通过其他途径分发给其他对象变量做处理。
大部分的事件可以在你的应用里分发,类似于触摸事件,远程操控事件(线控耳机等) 都是由app的 responder objects 对象处理的。
Responder objects 在你的app里到处都是,比如:UIApplication 对象,view对象,view controller 对象,都是resopnder objects。大部分事件的目标都指定了resopnder object,不过事件也可以传递给其他对象。比如,如果view对象不处理事件,可以传给父类view或者view controller。
图片及内容来源:应用程序生命周期
goyohol's essay