下面咱们来分析一下erget中的生命周期。ide
src/egret/player/SystemTicker.ts:函数
export namespace lifecycle { export type LifecyclePlugin = (context: LifecycleContext) => void; /** * @private */ export let stage: egret.Stage; /** * @private */ export let contexts: LifecycleContext[] = []; let isActivate = true; export class LifecycleContext { pause() { if (isActivate) { isActivate = false; stage.dispatchEvent(new Event(Event.DEACTIVATE)); if (onPause) { onPause(); } } } resume() { if (!isActivate) { isActivate = true; stage.dispatchEvent(new Event(Event.ACTIVATE)); if (onResume) { onResume(); } } } onUpdate?: () => void; } export let onResume: () => void; export let onPause: () => void; export function addLifecycleListener(plugin: LifecyclePlugin) { let context = new LifecycleContext(); contexts.push(context); plugin(context); } }
LifecycleContext定义了监听生命周期的类,pause(),resume(),update()这个三个成员方法分别执行暂停、继续和刷新。LifecyclePlugin定义了一个监听应用程序状态变化的函数类型,它有一个类型为LifecycleContext的context参数。addLifecycleListener()方法建立了LifecycleContext的一个实例,把这个实例做为参数调用了传入的plugin()方法。
这样看好像有点乱,咱们梳理一下。spa
export type LifecyclePlugin = (context: LifecycleContext) => void;
由于不一样平台监听应用程序状态变化的实现不一样(Native平台要应用到原生接口,Web使用一些Javascript的API),它们的共同点是要用到LifecycleContext的一个实例,在对应的监听实现代码里去调动这个实例的pause(),resume(),update()这三个方法去暂停、继续和刷新应用程序,因此定义了LifecyclePlugin这个函数类型。code
export function addLifecycleListener(plugin: LifecyclePlugin) { let context = new LifecycleContext(); contexts.push(context); plugin(context); }
addLifecycleListener()方法做为桥梁,接收到具体的LifecyclePlugin类型的函数,建立LifecycleContext的一个实例做为参数调用它。接口
let isActivate = true; export class LifecycleContext { pause() { if (isActivate) { isActivate = false; stage.dispatchEvent(new Event(Event.DEACTIVATE)); if (onPause) { onPause(); } } } resume() { if (!isActivate) { isActivate = true; stage.dispatchEvent(new Event(Event.ACTIVATE)); if (onResume) { onResume(); } } } onUpdate?: () => void; } export let onResume: () => void; export let onPause: () => void;
isActivate做为一个布尔值类型的成员属性用来标记当前是否暂停,这个if语言的做用是防止重复触发暂停事件,若是触发,主要作了两件事情,一个是向全局事件系统触发了一个Event.DEACTIVATE类型的事件(关于全局事件系统在后面的章节中具体分析)。一个是调用了onPause()方法。咱们在egret-core/tools/templates/game/src/Main.ts中找到这几行生命周期
private onAddToStage(event: egret.Event) { egret.lifecycle.addLifecycleListener((context) => { // custom lifecycle plugin context.onUpdate = () => { console.log('hello,world') } }) egret.lifecycle.onPause = () => { egret.ticker.pause(); } egret.lifecycle.onResume = () => { egret.ticker.resume(); } //设置加载进度界面 //...... //初始化Resource资源加载库 //...... } /** * 心跳计时器单例 */ export let ticker: sys.SystemTicker = new sys.SystemTicker();
这里延迟定义了onPause()方法,这个方法只有一行,执行了egret.ticker.pause()方法。resume()方法相似pause()方法。事件
egret-core/src/egret/native/NativeHideHandler.ts:ip
namespace egret.native { /** * @private */ export let NativeLifeCycleHandler: egret.lifecycle.LifecyclePlugin = (context) => { egret_native.pauseApp = () => { context.pause(); egret_native.Audio.pauseBackgroundMusic(); egret_native.Audio.pauseAllEffects(); }; egret_native.resumeApp = () => { context.resume(); egret_native.Audio.resumeBackgroundMusic(); egret_native.Audio.resumeAllEffects(); }; } }
这个Native平台监听函数定义了原平生台的两个方法egret_native.pauseApp()和egret_native.resumeApp()。pauseApp()函数作了两件事情:暂停应用程序,暂停背景音乐和音效的播放。resumeApp()相似。资源
egret-core/src/egret/native/NativePlayer.ts:get
namespace egret.native { /** * @private */ export class NativePlayer extends egret.HashObject implements egret.sys.Screen { //... private init(option: PlayerOption): void { //... lifecycle.addLifecycleListener(NativeLifeCycleHandler); //... } //... } }
这里利用addLifecycleListener()方法绑定了NativeLifeCycleHandler()这个函数。