Browse > Home

| Subcribe via RSS

周期定时器:一个Flash Player10.1中不得不关注的特性

六月 22nd, 2010 | No Comments , 1 views | Posted by flashlizi in Flash CS3/AS3

在Flash Player 10.1中,Adobe引入了一个全新的Periodic timer定时器概念,它可以改善浏览器中swf内容的CPU使用。在浏览器中的swf文件在不可见状态下(如窗口最小化,隐藏标签tab或页面滚动到swf文件以外的区域)会自动调节以降低资源消耗。(注:之前的Flash Player版本虽然不会渲染图形,但仍然在全速运行AS脚本,音视频编码解码等。)具体改变如下:

可见状态下:
1)SWF的帧频frameRate会被限制和校准为Jiffy时间模式(如最高60fps),但是目前的10.1 beta3仍然保留最高120fps的限制,这在正式版中将会被改变。
2)计时器(AS2中的Interval和AS3中的Timer)也会校准为Jiffy。
3)LocalConnection也同样会被校准。因此消息从一个swf文件到另一个swf文件至少需要33ms(也有说是40ms)。
4)Video不会做改变,他们可以在任何帧频下播放而不受影响。

不可见状态下:
1)SWF的帧频被锁定为2fps,不进行任何渲染。
2)计时器(AS2中的Interval和AS3中的Timer)被锁定为最多2次/秒。
3)LocalConnection也被锁定为最多2次/秒。
4)Video视频解码(不渲染和显示)只占用CPU空闲时间。
5)为了兼容音频,当swf中有音频在播放的时候,swf的帧频会被调整为8fps,同样swf中计时器和LocalConnection也做相应调整。

应该说这个特性非常有利于网络上flash应用的普及,但是也存在着潜在的风险。比如某些情况下,我们的应用程序需要在不可见的时候仍然保持着正常的运转,比如计时器的正确运行,某些事件按时发生,某些下载任务及时进行等等。当swf的帧速下降到2fps的时候,其影响是显而易见的。因此我们需要在swf不可见的时候仍然保持较高或者正常的帧速。目前有两种解决方法:

利用播放一个音频来使swf在不可见状态下维持8fps:
var gs:Sound = new GhostSound();
gs.play(0, int.MAX_VALUE, new SoundTransform(0));

用js的setInterval方法去调用swf的ExternalInterface.addCallback的方法,从而间接实现一些在不可见状态下必须全速运行的一些动作:
setInterval(callSWF, 50);
function callSWF()
{
var swf=document.getElementById("swfID");
if(swf)swf.execSomeMethod();
}

元标签注入式MVC框架: InjectMVC

五月 31st, 2010 | 1 Comment , 1 views | Posted by flashlizi in Design Pattern, Flash CS3/AS3

什么是依赖注入(Dependency Injection)?

依赖注入DI在我们编程中其实随处可见,你也可能正在用构造函数注入,setter注入,属性注入等。网上资料随处可以见,在此就不赘述。

什么是元标签(metadata)注入?

有过flex编程经验的可能都知道如[SWF]、[Bindable]、[Event]这样的元标签metadata,flex编译器会根据不同的metadata
会赋予swf特定的属性或者生成特定的as代码来达到我们的目的。 当我们加上-keep-as3-metadata+=MetaName这样编译参数后,编译器会把指定的metadata保存到编译的swf中去。当你再用describeType()方法获取某个有metadata标记的类的XML描述的时候,你会看到你定义的metadata。基于这样的原理,我们便可以利用这一特性实现特殊的注入。

什么是元标签注入式MVC框架?

这是本人根据这种框架的特性命名的。最典型的当属robotlegs (注:可参考eidiot翻译的robotlegs最佳实践)。本框架也是受了它很大的启发,当然InjectMVC有它自己的特点:可注入事件,框架更简单小巧等。(对robotlegs熟悉的朋友可以直接下载demo和源码了解InjectMVC的特别之处)

InjectMVC里Context的作用?

Context是InjectMVC的中枢,有点像puremvc里的Facade,它负责初始化和管理MVC的核心部分Model、View、Controller。 但它跟Facade不一样,它不是单例,可以被实例化。一般来说,一个context定义一个作用域。MVC成员Mediator、Proxy、Command在context范围内的相互通讯和协作。每个context对应一个显示对象application。

Context有一个非常重要的成员Injector,它负责映射和注入属性和事件给Mediator、 Proxy、Command。但你无需直接操作Injector,它已经被封装到context里,你要做的就是注册Mediator、Proxy、Command,并注入你所需要的属性和事件。Context还有一个contextDispatcher,它负责发送和响应context事件。

Context提供以下API供其MVC成员调用来完成彼此的通讯和协作:

* registerMediator
* getMediator
* removeMediator
* hasMediator
* registerProxy
* getProxy
* removeProxy
* hasProxy
* registerEvent
* removeEvent
* dispatchEvent

当你用上面的方法注册一个mediator,proxy或event的时候,InjectMVC会自动注入它们用[Inject]原标签定义的依赖,并保存它们的映射以供其他类注入使用。

比如,我们注册了这么一个mediator:
registerMediator(btn, ButtonMediator);

那么,我们在之的某个Command中便可以注入这个ButtonMediator:
package
{
public class CustomCommand extends Command
{
[Inject]
public var btnMediator:ButtonMediator;
override public function execute()
{
btnMediator.doSomeThing();
}
}
}

更多的文档请到这里参考wiki

InjectMVC相关下载:

* 演示(含源码)
* InjectMVC(源码及SWC)

SWC Maker (update: v0.6)

四月 4th, 2010 | 9 Comments , 1,536 views | Posted by flashlizi in Adobe AIR

SWC Maker是我这两天用Flash Builder 4开发的一个AIR 2程序,功能很简单,就是让打包AS3成SWC库变得更简单和更容易控制。使用步骤也很简单:

1. 在编译选项里配置你的Flex SDK路径;
2. 指定一个swc的输出目录和名字;
3. 添加或删除要打包的as3源文件(.as文件);
4. 添加或删除项目引用的swc类库(.swc文件);
5. 编译,查看结果。

目前功能比较简单,下一个版本将添加合并swc文件等功能,如果有什么bug或功能需求,都可以提出来。
目前最新版本0.6,更新日期:2010-5-18。
特别注意:更新程序运行时版本为AIR 2 RC(因最新的AIR 2 RC版上不能运行AIR 2 beta2的应用程序,因此如果你此前安装有SWCMaker0.4以前的版本,请到控制面板里卸载后再安装新版)

更新内容:
* 添加swc工程管理功能
* 添加语言支持(中文和英文)
* 界面优化

点击下载 SWCMaker0.6(本程序需要AIR 2 RC以上才能运行)

一个新的Flash Media Server

三月 31st, 2010 | 2 Comments , 1,777 views | Posted by flashlizi in News

ProcessOne刚刚发布了他们的一款用erlang编写的Flash媒体服务器OneTeam Media Server。尽管这次发布的版本功能不像FMS或Red5那样全面,但他们2年前就已经开始开发这个项目了,因此据说性能不错。

它的主要特性有:
1. 支持流式播放实时或已录制好的媒体内容
2. 支持录制实时内容
3. 支持AS3 SharedObject 共享对象
4. 支持Clustering集群
5. 支持用Erlang/OTP编写应用程序模块

目前,OMS还不支持RTMPT。OMS是开源程序,不过因为它不支持Windows系统,所以我还没有时间去尝试。有兴趣的朋友可以去下载试试看。

Tags:

Gumbo Skinning:强大的Flex4组件皮肤自定义功能

六月 9th, 2009 | 3 Comments , 1,834 views | Posted by flashlizi in Flex4(Gumbo)

Flex4与flex3相比有着非常大的变化,而全新的组件皮肤自定义(Gumbo Skinning)最能集中体现flex4的优点。组件功能逻辑与显示分离,布局独立于组件,统一的组件皮肤自定义方式,再加上FXG(Flex Graphics)强大的绘图功能,我们甚至可以抛弃PS、CS3等工具,完全用MXML定制出非常漂亮的组件。

下面是我今天做的一套flex4的组件皮肤,无任何外部图形,大家可以看一下flex4 skinning的效果(需要安装flash player10):


点击下载源文件>>>

Flex 4系列:认识flex 4中的命名空间namespace

六月 4th, 2009 | No Comments , 1,378 views | Posted by flashlizi in Flex4(Gumbo)

Flex 4(gumbo)定义了如下3个命名空间:

1、xmlns:fx=”http://ns.adobe.com/mxml/2009″
这是MXML 2009版的命名空间,它包含了AS3的最顶层(top-level)的基本元素,如Object、Array、Boolean、String、Number、Vector、XML等,详细列表可参看Flex SDK下的framwork目录下的mxml-2009-manifest.xml清单文件。另外,它还包括了一些MXML编译器的标签,如<fx:Script>、<fx:Style>、<fx:Binding>、<fx:Metadata>、<fx:Component>、<fx:Declarations>等。

2、xmlns:mx=”library://ns.adobe.com/flex/halo”
这是Helo组件的命名空间,它包含了所有mx包里的组件。详细列表可参看Flex SDK下的framwork目录下的halo-manifest.xml清单文件。

3、xmlns:s=”library://ns.adobe.com/flex/spark”
这是Spark组件的命名空间,它包含了所有spark包和flashx(新的文本布局组件textLayout)包里的组件。另外,为了方便,它还包含了mx包里的RPC相关的类和states、graphics、effect等,当然你仍然可以使用mx命名空间来使用这些类和组件。详细列表可参看Flex SDK下的framwork目录下的spark-manifest.xml清单文件。

如果你用gumbo来开发或编译flex3的项目的时候,你仍然可以使用flex3的MXML命名空间xmlns:mx=http://www.adobe.com/2006/mxml,但是它不能和MXML 2009的fx命名空间混合使用。

想了解更多内容的话,你可以参看MXML 2009说明书

创建高性能AIR程序的几点提示

五月 22nd, 2009 | No Comments , 2,546 views | Posted by flashlizi in Adobe AIR

1、尽量降低应用程序的帧频frameRate。如12,7等。
2、动态改变frameRate来适应程序的需要。当需要展示一个动画的时候,可以临时增加帧频来让动画更加平滑顺畅,动画完成后再把帧频降低。另外,当AIR程序在后台运行的时候,可以把帧频调至0.1甚至0,并临时注销一些ENTER_FRAME或Timer事件处理器,这样能有效降低AIR程序的空闲资源的占有。
3、尽量少用ENTER_FRAME事件,或者用Timer代替。合并可能的Timer,减少同时处理Timer的数量。

用Flex的编译参数实现AS3程序的自身预加载(Self Preloading)

四月 6th, 2009 | 6 Comments , 1 views | Posted by flashlizi in Flex3

记得在很早的时候,我在blueidea上写过一个关于as3自身加载的帖子,基本思想和as2中的原理类似,而且还曾被人批评为帧的概念太根深蒂固,as3中要完全抛弃frame。今天,我的一个flashdevelop的as3项目需要做个loading,我不觉得一个小swf去加载大的swf文件是一种很好的loading解决方案。 因为用的是flex sdk,没法像flash CS3那样创建帧,又不想创建一个fla文件,所以原来的办法似乎没法用了。

于是我翻出以前bit-101上的一片经典的as3自身加载的文章:Preloaders in AS3,仔细看看后,发现原来的想法是正确的,只不过在flex中靠的是元数据标签Frame来增加一个工程关键帧类factoryClass,而这个类在flex项目中默认为mx.managers.SystemManager,并由此控制flex程序的preloading实现。说白了,就是flex程序的其实都是2帧,第一帧默认是SystemManager类的实例,第二帧才是我们的Application文档类mxml。再进一步查看flex的as3 compiler的源程序,也证实了这点。

可是,当我用元数据标签Frame来加入preloading的时候,编译后的swf文件尺寸陡增,原来当用元数据标签Frame加入factoryClass的时候,就会编译很多flex框架类到swf中来,显然这不是我所期望的,这个方法也行不通。但用双帧原理来做preloading是显然的,因此问题的关键便在于如何创建一个双帧的swf。

当我在flex的as3 compiler的源程序中寻找的时候,突然在flex的编译程序mxmlc的编译参数中看到了一个高级可选参数frames.frame,搜索后找到这个参数在flex-config.xml中的具体用法:
<frames>
      <!-- frames.frame: A SWF frame label with a sequence of classnames that will be linked onto the frame.-->
      <!-- frames.frame usage:
      <frame>
         <label>string</label>
         <classname>string</classname>
      </frame>
      -->
</frames>

这个参数用mxmlc的cmd命令行参数模式为:
-frames.frame label classname

于是我在flashdevelop的项目属性的compiler options里的Additional Compiler Options里加入是一个已有但并未编译到文档类里的类FrameTwoClass:
-frames.frame FrameTwoClass FrameTwoClass
果然,在编译后的swf文件的classes里可以看到一个Frame 2: FrameTwoClass的类,因此便很容易知道,这个参数可以帮我们创建帧并链接到一个指定的类。

到这里为止,我想大家应该都差不多已经知道怎么实现self preloading了吧。创建一个Preloading类并设置为文档类,把我们真正的主程序Application类用刚才的参数frames.frame编译到第二帧上。在Preloading类中用enterframe事件监听loaderInfo的bytesLoaded和bytesTotal从而显示加载进度,当加载完后,利用反射方法getDefinitionByName()来创建真正的主程序Application类的实例,大功告成!

点击查看 demo源文件

Tags:

Debug flash apps with firebug

三月 26th, 2009 | No Comments , 1,094 views | Posted by flashlizi in Flash CS3/AS3

大家应该都有用firebug的经验,现在提供2个类Console和Trace,Console可以将指定的debug的内容输出到firebug的控制面板,Trace则可以在firebug的console中trace页面中的flash里的对象和属性等。使用示例如下:
package
{
import flash.display.Sprite;
public class Main extends Sprite
{
public var version:String = "version 1.0";
public var info:Object = { name:"debug_demo", author:"alex", date:"2009-3-26" };
public function Main():void
{
Console.log("This a flash debug demo!");
Console.dump(info);
Trace.bind('main', this);
}
}
}

上面示例在firebug中的输出和trace截图如下:
firebug_screenshot

源文件和Demo下载>>>

用MSNContact Library获取MSN联系人列表

二月 25th, 2009 | 4 Comments , 1,316 views | Posted by flashlizi in Flash CS3/AS3

这是最近在做的一个项目中的一部分,功能就是根据你的MSN帐户和密码获取MSN好友列表。不过要注意因为此组件需要连接微软的MSN远程服务,所以会有安全沙箱问题,在debug状态或者添加了全局安全设置之后就不会报安全错误,当然最适合在AIR项目中使用了。
点击下载SWC组件>>

使用方法:
import com.riaidea.msn.MSNAccount;
import com.riaidea.msn.MSNContact;
var email:String = "your email address";
var password:String = "your msn password";
var account:MSNAccount = new MSNAccount(email, password);
account.addEventListener(Event.INIT, initHandler);

function initHandler(evt:Event):void
{
account.removeEventListener(Event.INIT, initHandler);
//在MSNAccount发出INIT事件后,即可用getContacts()方法获取Contact数组列表。
//数组的每个元素都是一个MSNContact对象,包含id,email,nickname三个属性。
for each(var c:MSNContact in account.getContacts())
{
trace(c); //或trace(c.id, c.email, c.nickname);
}
}