常用mime-type
.flv video/x-flv
走上新的起点-走Flash、Flex、Air、Fms的应用开发路线
.flv video/x-flv
原文:http://eidiot.net/2007/06/03/applicationdomain/
当程序越来越大,我们需要把它拆分成多个swf,在需要的时候动态加载。拆分时应该尽量把不同的类编译进唯一的swf,避免因swf文件增多而使整个程序的文件尺寸增大。按此原则可以拆分出以下两种swf,借助 ApplicationDomain 共享其代码和资源。
ApplicationDomain 是存放AS3定义(包括类、方法、接口等)的容器。使用Loader类加载swf时可以通过指定 ApplicationDomain 参数将swf加载到不同的域(Domain):
var loader : Loader = new Loader();
var context : LoaderContext = new LoaderContext();
/* 加载到子域(模块) */
context.applicationDomain = new ApplicationDomain(ApplicationDomain.currentDomain);
/* 加载到同域(共享库) */
context.applicationDomain = ApplicationDomain.currentDomain;
/* 加载到新域(独立运行的程序或模块) */
context.applicationDomain = new ApplicationDomain();
loader.load(new URLRequest("loaded.swf"), context);
ApplicationDomain使用类似于显示列表(DisplayList)的树形结构。 相对于舞台(Stage) ,可以认为 ApplicationDomain 最根部的是系统域(system domain),包含 Flash Player 核心类定义。主程序所在的域(以下简称主域)就是它唯一的子域,类似于Stage下的文档类(Document Class)。
一个fla文档类里代码:
this.stage.addChild(mySprite);
this.addChild(myMC);
this.addChild(myShape);
运行后的显示列表:
ApplicationDomain 的类似结构: 
模块加载到同域不是一样可以吗?为何要加载到子域呢?好处就在于,卸载一个加载到子域的模块时,只要确保清除所有到该模块的引用,模块的所有类定义将被垃圾回收(Garbage Collection)。
有两种方式可以访问 ApplicationDomain :
ApplicationDomain 的 hasDefinition() 方法判断某定义是否存在,getDefinition() 方法获取指定的定义。下面以一个 例子 来介绍 ApplicationDomain 的具体用法和应用程序的拆分。
本例 有四个swf,shell.swf是主程序,lib.swf是共享库,login.swf和result.swf分别是“登录”和“结果”模块,所有的视图元件都在共享库中。实际开发时可能有很多库,比如“位图库”、“音效库”、“模型通用库”等。“通用库”里存放多个模块共用的资源,比如此例中的背景元素。而各个模块独有的资源还是放在各自的swf中。
主程序首先将共享库加载到同域,完成后将“登录模块”加载到子域。主程序可以像操作普通的视觉对象(DisplayObject)一样操作加载的模块:监听事件、调用方法。因为编译器不会识别未定义的类,为使用强类型,建议为主类和模型定义相应的接口,使用少量的重复代码协助编程。
private function showModule(p_module : IModule) : void
{
if (this.m_moduleList[0] == "login.swf")
{
p_module.show(this);
p_module.addEventListener("login", this.onLogin);
} else
{
p_module.show(this, this.m_userName);
}
}
模块“继承”了主程序和共享库的所有类和资源,可以通过 ApplicationDomain.currentDomain.getDefinition() 来获取相应的类。注意获取不存在的类会抛出一个 ReferenceError。
protected function getClass(p_name : String) : Class
{
try
{
return ApplicationDomain.currentDomain.getDefinition(p_name) as Class;
} catch (p_e : ReferenceError)
{
trace("定义 " + p_name + " 不存在");
return null;
}
return null;
}
登录模块获取库中的界面元素,并在点击按钮后抛出事件。Event类不允许带参数,必须使用继承Event的自定义事件抛出参数。主程序可以把模块的自定义事件也编译进去(这样就增大了整个程序的文件尺寸),或者让监听模块事件的函数接受一个Objcet参数,以获取其动态属性。
private function onLogin(p_e : Object) : void
{
this.m_userName = p_e.userName;
var login : IModule = p_e.currentTarget;
login.removeEventListener("login", this.onLogin);
login.dispose();
this.loadSwf();
}
主程序收到事件之后卸载注册模块,加载“结果模块”到子域,并将登录模块传出的”userName”参数传给结果模块。
public function show(p_parent : DisplayObjectContainer, … rest) : void
{
var libClass : Class = this.getClass("net.eidiot.appDomainDemo.Libaray");
if (libClass != null) this.initUi(libClass, rest);
}
override protected function initUi(p_libClass : Class, p_rest : Array = null) : void
{
this.addUi(this.getClass(p_libClass.BG_NAME), "结果");
var resultFunc : Function = p_libClass.getResult;
var userName : String = p_rest[0];
this.addChild(resultFunc(userName));
}
注意initUi()方法分别使用了共享库中Libaray类的静态属性BG_NAME和静态方法getResult()。但是直接调用此静态方法会报错,可以先用 resultFunc 变量取出此方法。详细内容请参考 源代码。
通过经纬度坐标作为参数执行 Google Weather API, 例如:
http://www.google.com/ig/api?hl=zh-cn&weather=,,,30670000,104019996
(30670000,104019996 为 成都, 中国大陆 的经纬度坐标)
通过城市名称的汉语拼音来查询,例如:以下是北京的天气
http://www.davidpett.com/actionscript-3-managing-memory/
I have been doing a lot of work in trying to minimize memory and file size in my flash/actionscript projects, because of the structure of actionscript 3 most of this is a manual process. One of the first things you can do is when adding an event listener, use the optional parameters:
_btn.addEventListener(MouseEvent.CLICK, btnClick, false, 0, true);
The last optional parameter in the addEventListener function is useWeakReference, which by default is set to false, according to the ActionScript 3.0 Documentation, this parameter “Determines whether the reference to the listener is strong or weak. A strong reference (the default) prevents your listener from being garbage-collected. A weak reference does not.”
Another standard that I have imemented is to use the REMOVED_FROM_STAGE event in every class that I write. In this class I remove any display objects that I have added and remove all event listeners that those display objects have, because just removing an object does not do this and hose event listeners will still be there takin up memory and can hinder performance.
package
{
import flash.display.*;
import flash.events.*;
public class MyClass extends Sprite
{
private var _btn:Sprite;
//———————————–
// CONSTRUCTOR
//———————————–
public function MyClass():void
{
addEventListener(Event.ADDED_TO_STAGE, init, false, 0, true);
}
//———————————–
// INIT
//———————————–
private function init(e:Event):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
addEventListener(Event.REMOVED_FROM_STAGE, dispose, false, 0, true);
_btn = new Sprite();
_btn.addEventListener(MouseEvent.MOUSE_OVER, btnOver, false, 0, true);
_btn.addEventListener(MouseEvent.MOUSE_OUT, btnOut, false, 0, true);
_btn.addEventListener(MouseEvent.CLICK, btnClick, false, 0, true);
_btn.buttonMode = true;
addChild(_btn);
}
//———————————–
// DISPOSE
//———————————–
private function dispose(e:Event):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
removeEventListener(Event.REMOVED_FROM_STAGE, dispose);
if(_btn)
{
_btn.removeEventListener(MouseEvent.MOUSE_OVER, btnOver);
_btn.removeEventListener(MouseEvent.MOUSE_OUT, btnOut);
_btn.removeEventListener(MouseEvent.CLICK, btnClick);
try
{
removeChild(_btn);
}
catch(e:Error){trace("error: MyClass: dispose: removeChild(_btn): " + e)}
_btn = null;
}
}
}
}
http://dispatchevent.org/mims/creating-weak-references-in-as3/
For those of you not familiar with the concept, a weak-reference is a reference to an object that will not hold the linked object in memory when that object is garbage collected.
There are only two ways to create a weak reference in AS3. The first is with the IEventDispatcher.addEventListener() method which allows you to create a weak link between the dispatcher and the listener. To quote the AS3 Bible:
ActionScript 3.0 introduces the concept of weak and strong memory references. Normally, an object will be garbage collected if there are no references to the object. That is, when no objects are using a variable, it gets thrown out. Weak references allow you to reference an object but the object will still be eligible for garbage collection unless another object holds a strong reference to the object. By setting the [
addEventListener()method's]useWeakReferenceflag to true, you will create a weak link between the event broadcaster and the event listener. That way, if an dispatcher is deleted while there are still listeners attached, the weak reference will allow it to be garbage collected. This helps to prevent memory leaks.
The other way is with the objects used as keys in a Dictionary object.
ActionScript, unlike many other languages, does not have a way to explicitly remove an object from memory. Instead it waits until all references to an object are removed and then auto-deletes it. Therefore, an object will continue to stay in memory if all strong references aren’t removed.
Below is an example of how strong-references hold an object in memory. If you’d like to try this out, copy the below text into a file called StrongReferencesExample.as
package {
import flash.display.Sprite; public class StrongReferencesExample extends Sprite {
public function StrongReferencesExample() {
// create a new object called dog. Add it to the first leash object
// and make leash2 a copy of leash 1.
var leash1:Object = new Dog();
var leash2:Object = leash1; // tracing both leashes will show that they hold a reference to the Dog
trace(leash1); // [object Dog]
trace(leash2); // [object Dog] // deleting the dog from the first leash will not remove it from the second leash
// even though we originally set leash2 equal to leash1
leash1 = null;
trace(leash1); // null
trace(leash2); // [object Dog] // The object (dog) will not be free until all of the references to it (leashes) are broken.
leash2 = null;
trace(leash1); // null
trace(leash2); // null
}
}
}
// Define a simple Dog class within the same file.
class Dog {}
Richard Lord over at Big Room Games has an interesting article on hacking AS3 to allow you to create weak-references to objects. The hack is pretty decent but lacks a few things I’d like to see like strong typing at compile-time or a more refined ‘memory manager’ type functionality. However, I tried implementing both of these and came up empty handed. If you can think of a way to make this strong-typed, I’ll give you a candy bar.
Using the WeakReference hack could be useful if you want to make sure that an object will not stay in memory if you forget to delete all references to it. However, keeping track of your objects and practicing good memory management is a much better solution and hacks like this one should be saved for special cases where tracking use of an object becomes difficult or impractical.
Thanks to Alex for the link!
1424-4008-9664-3602-3439-1711
1、Yahoo的Flash开源组件
优点是纯ActionScript,可用于Flash和Flex中,基本功能都有,小巧,上手快,使用灵活,代码量不大,扩展性比较强。用在对功能没有太高要求的小型项目中,最合适不过。
比较傻瓜化的一个工具,使用时直接按照格式提供数据源即可,所有的功能都已经封装好了,都不需要编写代码。对于非Flash开发者来说,还是很实用的。
3、Axiis
一个针对Flex环境的可视化开发框架,功能很强大,绘图方面使用的是Degrafa工具库。官方站点上提供的Demo都很吸引人。
由于是针对Flex环境,所以使用起来很方便,可以用MXML代码来拖拽编辑。 实际测试运行了几个例子,感觉性能不太理想。一些例子程序,在中等配置的机器上跑,当数据量增到100以上,能感觉到鼠标提示和屏幕重绘有明显延迟。另外,由于使用了Degrafa工具库,最后生成的SWF体积颇大。
4、Flare(推荐)
从性能和效果上看,个人觉得,Flare比Axiis要强不少,看看这个Demo就知道了。Flare更像一个图形引擎,其中的树形图效果真的是很惊艳。
Flare使用ActionScript开发,所以没有什么限制,唯一的缺点大概是上手不太容易,要熟悉使用需要花些功夫。
5、BirdEye
又一个超强的框架,目前还处于开发中,可以通过svn取源码,我还没有自己试过,但看看Demo,就知道这个绝对是值得期待的。