APP应用程序的生命周期

来源:互联网 发布:动画大师for mac 编辑:程序博客网 时间:2024/05/14 06:37

APP应用程序之所以有生命周期,是因为手机端的资源总是有限的,如果开启了一个APP应用就一直占用着手机资源而不释放,这样就会造成手机资源的消耗殆尽,也因此会对设备的电池、流量、用户交互体验造成影响。所以通过APP应用程序的生命周期,首先是更好的控制APP应用程序,其次是更好的控制及使用手机资源、用户交互体验。

APP应用程序状态

(1)Not running:未运行,即程序没启动
(2)Inactive:未激活,即程序在前台运行,不过没有接收到事件。在没有事件处理情况下程序通常停留在这个状态
(3)Active:激活,即程序在前台运行而且接收到了事件。这也是前台的一个正常的模式
(4)Backgroud:后台,即程序在后台而且能执行代码,大多数程序进入这个状态后会在在这个状态上停留一会。时间到之后会进入挂起状态(Suspended)。有的程序经过特殊的请求后可以长期处于Backgroud状态
(5)Suspended:挂起,即程序在后台不能执行代码。系统会自动把程序变成这个状态而且不会发出通知。当挂起时,程序还是停留在内存中的,当系统内存低时,系统就把挂起的程序清除掉,为前台程序提供更多的内存。

如图所示



APP应用程序各运行状态代理方法(6个常用方法)

(1)启动基本完成程序准备开始运行

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { return YES;}


(2)将要进入非活动状态执行,在此期间,应用程序不接收消息或事件,比如来电话了

- (void)applicationWillResignActive:(UIApplication *)application { }


(3)进入到后台的时候调用。所以要设置后台继续运行,则在这个函数里面设置即可

- (void)applicationDidEnterBackground:(UIApplication *)application { }


当应用程序进入后台时,我们可以做以下相关操作,如:
1)保存用户数据或状态信息,所有没写到磁盘的文件或信息,在进入后台时,最后都写到磁盘去,因为程序可能在后台被杀死,
2)释放尽可能释放的内存(如:图片对象、大的视频或数据文件等)
注意:在方法”applicationDidEnterBackgound: ”中,大概只有5秒的时间进行操作。如果超过时间还有未完成的任务,应用程序就会被终止而且从内存中清除。如果还需要长时间的运行任务,可以调用方法”beginBackgroundTaskWithExpirationHandler”去请求后台运行时间和启动线程来运行长时间运行的任务。


(4)从后台将要重新回到前台的时候调用

- (void)applicationWillEnterForeground:(UIApplication *)application { }


(5)进入活动状态执行
- (void)applicationDidBecomeActive:(UIApplication *)application { }
(6)将要退出是被调用,通常是用来保存数据和一些退出前的清理工作。

- (void)applicationWillTerminate:(UIApplication *)application { }


当一个基于警告式的中断发生时,比如有电话打进来了,这是程序会临时进入inactive状态,这用户可以选择如何处理这个中断。
如,按锁屏键也是另外一种程序的中断,当你按下锁屏键,系统屏蔽了所有触摸事件,把app放到了后台,这时app状态是 inactive,并进入后台。
当有这些中断时,我们的app该怎么办呢?我们应该在方法”applicationWillResignActive:”中处理相关操作,如:
1)停止 timer 和其他周期性的任务
2)停止任何正在运行的请求
3)暂停视频的播放
4)如果是游戏那就暂停它
5)减少OpenGL ES的帧率
6)挂起任何分发的队列和不重要的操作队列(你可以继续处理网络请求或其他时间敏感的后台任务)。
当程序回到 active 状态,我们应该在方法”applicationDidBecomeActive:”中重新开始相关操作,比如重新开始timer、继续分发队列、提高OpenGL ES的帧率。
特别说明,游戏要回到暂停状态,不能自动开始。


注意事项:
(1)Main Run Loop 主运行循环
Main Run Loop负责处理用户相关的事件。
UIApplication对象在程序启动时启动main run Loop,它处理事件和更新视图的界面。看Main Run Loop就知道,它是运行在程序的主线程上的。这样保证了接收到用户相关操作的事件是按顺序处理的。即大部分的事件可以在你的应用里分发,类似于触摸事件,远程操控事件(线控耳机等)都是由app的 responder objects 对象处理的。Responder objects 在你的app里到处都是,比如:UIApplication 对象。view对象,view controller 对象,都是resopnder objects。大部分事件的目标都指定了resopnder object,不过事件也可以传递给其他对象。比如,如果view对象不处理事件,可以传给父类view或者view controller。
1)用户操作设备,相关的操作事件被系统生成并通过UIKit的指定端口分发。
2)事件在内部排成队列,一个个的分发到Main run loop 去做处理。
3)UIApplication对象是第一个接收到时间的对象,它决定事件如何被处理。
4)触摸事件分发到主窗口,窗口再分发到对应出发触摸事件的View。
5)其他的事件通过其他途径分发给其他对象变量做处理。




(2)main函数
main函数是程序启动的入口,在iOS app中,main函数的功能被最小化,它的主要工作都交给了UIKit framework

#import <UIKit/UIKit.h>     int main(int argc, char *argv[])  {      @autoreleasepool {          return UIApplicationMain(argc, argv, nil, NSStringFromClass([MyAppDelegate class]));      }  }  

int UIApplicationMain(int argc, char *argv[], NSString * __nullable principalClassName, NSString * __nullable delegateClassName);
参数1:argc 包含了系统带过来的启动时间
参数2:argv[] 包含了系统带过来的启动时间
参数3:principalClassName 确定了主要应用程序类的名称,这个参数通常指定为nil
参数4:delegateClassName 程序自定义的代理类名,这个类负责系统和代码之间的交互,它一般在Xcode新建项目时会自动生成

UIApplicationMain函数加载了程序主界面的文件
虽然这个函数加载了界面文件,但是没有放到应用程序的windows上,你需要在Delegate的 application:willFinishLaunchingWithOptions方法中加载它。
一个应用程序可以有一个主的storyboard文件或者有一个主的nib文件,但不能同时有两个存在。
如果程序在启动时没有自动加载主要的storyboard或nib文件,则可以在方法”application:willFinishLaunchingWithOptions”里设置windows的展示,如:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    // Override point for customization after application launch.        ViewController *rootVC = [[ViewController alloc] init];    UINavigationController *rootNav = [[UINavigationController alloc] initWithRootViewController:rootVC];    self.window.rootViewController = rootNav;    self.window.backgroundColor = [UIColor whiteColor];    [self.window makeKeyAndVisible];        return YES;}



0 0
原创粉丝点击