下面咱們來分析一下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()這個函數。