单的?Modular(模块)和Shell(?pDLL(动态链接库)和EXE(可执行程?之间的关pM?例如我们在写WINDOWS的应用程序的时候可以调用大量的MICROSOFT提供的DLL里的Ҏ(我们UC为API).同样?我们也可以自己把功能相同或者同cȝҎ抽象成ؓ动态链接库以方便我们的后箋开?升,团队开发等{? 因此昄,Modular的推出更有利于我们开发程序的模块?可能有h会说,q样的功能我们同样可以采用编译多个可执行SWF,然后用Loader载入不就行了?的确我不反对q样的做?事实证明,q也可以被正实施于未更新的版本?不一L?
1.例如我们在模块中包含Application的标{?大家可以ȝ一下它的依赖关pd知道Z么只写一个Helloworld׃生成>100K的原因了.而事?q些东西我们在主E序中其实是包含了这些类?cȝ重复被编译导致文件变得更?
2.Application标签是可以被q行?单的?Application~译的SWF可以直接q行,q样我们的编E似乎就成了EXE和EXE的嵌?g有点奇? 而Modular本n是不可执行的,pDLL一?里面可以包含很多Ҏ也可以包含许多窗?但事实自w是不可被运行的.而这些好处在Modular里可以轻杄实现.
好的,现在我们来直接一点吧,看一下例?
代码下蝲: http://res.ezse.com/Howto/ModularDemo.rar
我们在FLEX BUILDER里徏立三个项?一个专门放MODULARS,一个ؓSHELL,最后一个是Interface.当然,视需要我们也可以建立多个目.
当然,Shell(ModularMain)是我们的主E序,相当于我们的EXE文g;
Modulars(Modulars)是我们的DLL文g的聚集地J 当然合适的建立模块,可以使得我们的程序更h展性和部v.
Interface(UserModularsInterface)q不是必ȝ,但我在团队合作和大型E序开发的时候采用接?接口的具体功能我׃在这里说?可以找本OOD书看一?单的说就是模块之间合编E所l一的必ȝҎ或属?接口没有具体的实现方?只是声明了方法或属?
在这个例子中,我们建立了三个Modular,一个是在Shell目中的InnerModular.mxml . 另一个是在Modulars中的OuterModular.mxml . q个Modular和InnerModular怼. 最后一个是在Modulars中的OuterModularWithInterface.mxml . q个Modular和前两个区别不大,仅仅是用了Interface(推荐使用q种方式).
首先我们看一下Inner Modular. Z么取名ؓInner Modular是因个Modular是和Shell在同一个Project?
InnerModular.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Module xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Script>
<![CDATA[
[Bindable]
public var textValue:String = "(default inner text value)";
]]>
</mx:Script>
<mx:Label text="{textValue}"/>
</mx:Module>
在源E序?唯一要注意的是我们新徏一个Application的时?U色标记部分是引用的Application标签.把它改ؓModule卛_.
引用?ModularMain.mxml?
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="init()">
<mx:Script>
<![CDATA[
import mx.modules.*;
import mx.events.ModuleEvent;
private var mdInnerModular:Object;
private function init():void
{
mdInner.addEventListener(ModuleEvent.READY,onInnerModularLoaded);
}
private function onInnerModularLoaded(evt:ModuleEvent):void
{
mdInnerModular = mdInner.child;
mdInnerModular.textValue = "Inner Modular";
}
private function CallIOuterModularFunction():void
{
var iOuter:IOuterModular = mdOuterWithInterface.child as IOuterModular;
iOuter.SetText("IOuter Called");
}
]]>
</mx:Script>
<mx:ModuleLoader id="mdInner" url="InnerModular.swf"/>
<mx:ModuleLoader id="mdOuter" url="assets/OuterModular.swf" y="20"/>
<mx:Button label="Set Outer Modular Value" click="(mdOuter.child as Object).textValue = 'Outer Modular'" y="40"/>
<mx:Button label="Call Outer Modular Function" click="(mdOuter.child as Object).testFunction()" y="70"/>
<mx:ModuleLoader id="mdOuterWithInterface" url="assets/OuterModularWithInterface.swf" y="90"/>
<mx:Button label="Call Outer Modular Function" click="CallIOuterModularFunction()" y="120"/>
</mx:Application>
Shell中的有红色部分是对InnerModular的操?注意的就是要执行Modular中的Ҏ或者更改属性必ȝModularLoader触发了ModuleEvent.READY 后才能执?
OuterModular.mxml:
<?xml version="1.0" encoding="utf-8"?>
<mx:Module xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Script>
<![CDATA[
[Bindable]
public var textValue:String = "(default outer text value)";
public function testFunction():void
{
this.textValue = "Outer Function Called";
}
]]>
</mx:Script>
<mx:Label text="{textValue}" />
</mx:Module>
内容和InnerModular一?不一L是放在了另一个Project?
而我推荐的是使用Interface.下面我们q一下用了Interface的操作方?
-
首先我们要定义Interface文g,Z方便,我们新徏立一个Lib Project.q样~译后会生成一个swc的可被引用的代码?
-
在Shell和Modular的Project中添加引?
-
在Modular中实现具体的接口中定义的Ҏ或属?
IOuterModular.as
package
{
import flash.events.IEventDispatcher;
public interface IOuterModular extends IEventDispatcher
{
function SetText(val:String):void;
}
}
在接口中,我们定义了SetTextq个Ҏ.于是我们在Modular中先实现q方?
OuterModularWithInterface.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Module xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" implements="IOuterModular">
<mx:Script>
<![CDATA[
[Bindable]
public var textValue:String = "(default outer(with interface) text value)";
public function SetText(val:String):void
{
this.textValue = val;
}
]]>
</mx:Script>
<mx:Label text="{textValue}" />
</mx:Module>
其中U色部分标记了此Modular为接口IOuterModular的实? 蓝色部分则是具体实现的方?
?span style="BACKGROUND-COLOR: yellow">ModularMain.mxml的橙色部分则是它的用方?
和不用接口不一L地方? var iOuter:IOuterModular = mdOuterWithInterface.child as IOuterModular;新徏一个实?此实体正是ModularLoader的child.q里可能要注意一?/span>,q个child可能是Flex的Bug,q个child是一个DisplayObject,例如我们q样写mdOuterModular.child.SomeFunction().~译无法通过,提示是DisplayObject没有q个Ҏ(废话).但是在调试模式下可以看到,q个childq一个DisplayObject. 因此很郁?必须把这个child 讄成Object才能执行里面的方?
用接口还有一个好?那就是可以直接看到Modular中的Ҏ和属?而在前两个例子中是没有这U功能的.
另一个要注意的地Ҏ,如果我们的Modular的Width,Height讄成的?00%, 而在ModularLoader中设|了Width和Height为绝对值的时?会发?事实?Modularq没有填充这个固定区? 做实验的话可以在Modular中设|一个Canvas.引用后会发现大小?x0.所以我们可能在写这U高宽不定的时?可能要徏立一个方?在Modular Ready后执行方法来重设|它的大?
现在我们可以看到E序可以正常的被执行?但是Modular生成出来的swf个个都是100多K! 当然,因ؓ我们q没有对Modulars Projectq行裁剪寸. q个裁减q程的原理就是我们的ȝ序中已经~译了的c?在Modular中就不再~译?而如何设|呢?在Shell的Project中的~译器的附加参数里设|ؓ-locale en_US -link-report=d:/testreport.xml q样在编译的时候会生成一个关于Shell里所引用q的cd列表在d:/testreport.xml的文件中. 在Modulars中的~译器的附加参数里设|ؓ-locale en_US -load-externs=d:/testreport.xml q样,在编译Modulars的时?载入Shell已经~译q的cd.在编译的时候就跌q些cd.再编译一?大小豁然了100K,变成?0多k.
在Dreamer的Blog上也有一翻译的文章大家也可以去看一? http://www.zhuoqun.net/article.asp?id=382

]]>