由于AIR是在运行时资源膨胀,占用了很多的宝贵的内存和CPU,导致AIR的运行速度很差。虽然很多的AIR应用看起来都陷入这样的圈套,但是它也可以不要这样。你可以通过很多种的技术开发一个轻量级的应用程序以对抗传统的程序执行。
帧频控制是一个减少CPU使用的简单的方法。在此文中,我讲解释什么是帧频控制和如何在执行你的应用程序中最好的利用帧频控制。
注:为了能够更好的理解此文,你得具备ActionScript和AIR应用程序开发的一些基本的知识。
什么是帧频控制
帧频控制是一种控制应用程序的帧频以达到增加应用程序表现能力的一种技术。(当在使用应用程序或者在空闲时候减少资源浪费)。在ActionScript3.0中,开发人员有一个非常有用的的属性-Stage。frameRate。这个宝贵的属性可以让你快速改变帧频。在之前的ActionScript版本中,我们只能在IDE设定它时候死磕。非常感谢,今时已不同往日,我们无需再忍受后台有一个延迟的使处理器如负重担的应用程序。
如何实现帧频控制
由于实现帧频控制其本质是设置Stage.frameRate 属性值为高或者为低的问题,这全都要开发者自己去决定。这个也取决于应用程序自己-有些应用程序比其它的允许更多的整合哦那个和。
注:以下示例的执行结果是在Macbook Pro 2.8 GHz Intel Core 2 Duo上面完成的。由于电脑CPU的使用条件不同,结果也会在不同的电脑有所差异。
新手级
最原始的控制形式是用过本地应用程序的Event.ACTIVATE 和Event.DEACTIVATE事件-当激活时增加帧频,非激活时降低帧频。对于一个单独的空白窗口,结果是CPU在激活时使用为1.8%,而非激活状态时是.4%。实际上你在非激活状态的时候设定帧频到.01可以达到CPU使用率为.2%,但是在测试的时候,我发现window chrome不会失焦。
package {
import flash.desktop.NativeApplication;
import flash.display.Sprite;
import flash.events.Event;
public class Application extends Sprite {
public function Application () {
__init ();
}
private function __init ():void {
NativeApplication.nativeApplication.addEventListener
(Event.ACTIVATE, __activate__);
NativeApplication.nativeApplication.addEventListener
(Event.DEACTIVATE, __deactivate__);
}
private function __activate__
($event:Event):void {
stage.frameRate = 50;
}
private function __deactivate__ ($event:Event):void {
stage.frameRate = 1;
}
}
}
中级
普通的应用程序允许更改的更高级的帧频控制-例如,一个需要一定交互的应用程序,即使是在后台。我们说,你的应用程序拥有可供参考的可滚动式的内容,由于AIR允许鼠标轮在不同的应用当中滚动,此时你需要一个更高的帧频。
在此示例中,如果应用程序是在后台,但是鼠标却在滚动,MouseEvent.MOUSE_WHEEL 的管理器增加帧频,设置一个Event.ENTER_FRAME事件将在滚动之后用来减少帧频。 为防万一,最好设置一个缓冲,这样你就不会在任何滚动的时候都改变帧频,同时,在鼠标轮空闲时也不会它也不会有监听的事件。
package {
import flash.desktop.NativeApplication;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.utils.getTimer;
public class Application extends Sprite {
public static const ACTIVE:int = 50;
public static const INACTIVE:int = 1;
public var active:Boolean;
public var scrolling:Boolean;
public var buffer:int;
public function Application () {
__init ();
}
private function __init ():void {
NativeApplication.nativeApplication.addEventListener
(Event.ACTIVATE, __activate__);
NativeApplication.nativeApplication.addEventListener
(Event.DEACTIVATE, __deactivate__);
stage.addEventListener
(MouseEvent.MOUSE_WHEEL, __mouseWheel__);
}
private function __activate__ ($event:Event):void {
active = true;
stage.frameRate = ACTIVE;
}
private function __deactivate__ ($event:Event):void {
active = false;
stage.frameRate = INACTIVE;
}
private function __mouseWheel__ ($event:MouseEvent):void {
if (!active) {
if (!scrolling) {
stage.addEventListener
(Event.ENTER_FRAME, __enterframe__);
}
stage.frameRate = ACTIVE;
scrolling = true;
buffer = getTimer () + 500;
}
}
private function __enterframe__
($event:Event):void {
if (buffer < getTimer ()) {
stage.frameRate = INACTIVE;
scrolling = false;
stage.removeEventListener
(Event.ENTER_FRAME, __enterframe__);
}
}
}
}
专家级
如果你生来是为优化程序而存在,那么你可以用一些比较复杂的帧频控制手段来让别人对你尖叫和景仰。(备:对你的女朋友无效)
在我的应用程序中,为了有一个更平滑的环境和一个更好的感觉,我喜欢让事物从一个状态转到下一个状态。有鉴于此,我比较喜欢用高帧频(50)。不幸的是,帧频越高,CPU利用也就越高。因此,我仅在一个补间动画(tween)激活的时候才使用50的帧频。当非补间动画激活的时候,我使用24的帧频。除此之外,当应用程序在后台且加载器(loader)运行的时候有很多元素(instances)。加载器并不需要50帧每秒(fps)的帧频,所以,当应用程序在后台可见时,我将把帧频设置到5,如果应用程序在后台不可见时,我会把帧频设置为1。
注:对于此示例,我会在每个补间动画前使用一个animate()方法来访问。理想的状况是,你会想要创建一个帧频控制器到你的补间动画引擎,所以你无需手动访问animate()方法。
package {
import flash.desktop.NativeApplication;
import flash.display.Sprite;
import flash.events.Event;
import flash.utils.getTimer;
public class Application extends Sprite {
public static const ANIMATING:int = 50;
public static const ACTIVE:int = 24;
public static const INACTIVE_VISIBLE:int = 5;
public static const INACTIVE_INVISIBLE:int = 1;
public var active:Boolean;
public var animating:Boolean;
public var buffer:int;
public function Application () {
__init ();
}
private function __init ():void {
NativeApplication.nativeApplication.addEventListener
(Event.ACTIVATE, __activate__);
NativeApplication.nativeApplication.addEventListener
(Event.DEACTIVATE, __deactivate__);
}
public function activate ():void {
if (!animating) {
stage.frameRate = ACTIVE;
}
}
public function deactivate ():void {
if (!animating) {
stage.frameRate = (stage.nativeWindow.visible) ?
INACTIVE_VISIBLE : INACTIVE_INVISIBLE;
}
}
public function animate ($duration:int = 1000):void {
stage.frameRate = 50;
buffer = getTimer () + $duration;
animating = true;
if (!animating) {
stage.addEventListener (Event.ENTER_FRAME, __checkBuffer__);
}
}
private function __activate__ ($event:Event):void {
active = true;
activate ();
}
private function __deactivate__ ($event:Event):void {
active = false;
deactivate ();
}
private function __checkBuffer__ ($event:Event):void {
if (buffer < getTimer ()) {
stage.removeEventListener
(Event.ENTER_FRAME, __checkBuffer__);
animating = false;
if (active) {
activate ();
} else {
deactivate ();
}
}
}
}
}
帧频控制是优化你的AIR应用程序的执行能力的一个小章节。这是你保持低资源消耗的入门级的步骤和基本的概念。这样的心里和练习可以很容易的带入更多的程序响应,增加用户的体验。
真的勇士,敢于面对惨淡的CPU利用率,让我们直面这人生-没有人喜欢蜗牛软件。