Adobe Flex迷你教程 — 合理使用Module分割项目以及对Module的使用

Posted by Kevin Luo at 2 January 2009

Category: Flex 迷你教程

Tags:

现在说说Module,这篇教程代码不是最重要的,怎么样合理的使用Module以及注意的问题才是关键,所以建议大家注意下面红色语句。Module,可以将我们的项目按需划分为N个模块,在编译时将项目编译为主文件以及N个module的swf。Module基本上可以分为两种:

1. 完整的Module,可以被外部app所使用 — 会将所有涉及到的引用编译到module中,主文件的体积得到缩减,但是Module本身的体积可能会很大,比如Module和主程序都应用了对象C,那对象C会被编译到主程序以及Module中,这样Module的体积就会很大。
2. 关联到主程序的Module — 比如Module和主程序都应用了对象C,那对象C会只编译在主程序中,从而减小Module的体积。我今天主要讲这一种Module,也是我们最常用到的。

了解了Module的种类,再简单说说使用Module要注意的地方。

1. 绝对不能在Module以外的地方直接引用Module中的对象。这样Module会被编译到引用它的模块中去,如果从主程序中引用,那么Module就实际上没有效果了。
2. 既然不能引用,那么建议对Module对象的使用用接口实现。在Module中实现接口方法,在外部使用这个接口不会导致Module被误编译。
3. Module可以引用主程序中的东西,但是不要引用其他Module中的东西。

Module可以做什么呢?我主要将Module用于以下下两种情况

1. 缩减主程序的体积,点击Module功能块时加载Module.
2. 再入主程序后在用户感觉不到的情况下预加载剩下的Module.

现在讲正题,在demo中我这样表现Module的使用。(为了体现Module的意义,主程序生成的大小是原始flex大小248K, module内嵌了两张图片是674K)

1. 如何创建Module.
2. 主程序中点击按钮加载Module PictureWindow.
3. 加载完毕后将模块添加到Box中,并通过接口调用PictureWindow中的方法setSelectIndex()设置显示的图片。

1. 如何创建Module.

可以通过New –> MXML Module –>Optmize for applicaiton –> OK 或者修改任意的已经创建好的Container组建(比如Canvas, panel)标签为Module,再或者继承Module的As class。

之后确保“鼠标右键项目”–> Property –> Flex Module 中有这个Module,没有的话点Add –> 选择Module的mxml或as文件 –>Optmize for applicaiton — > OK

2. 主程序中点击按钮加载模块PictureWindow.

这里我使用了ModuleManager来动态加载需要的Module。这比ModuleLoder要灵活的多。

private function loadModule():void{
m = ModuleManager.getModule(“PictureWindow.swf”); //设置Module地址,地址是编译后swf在bin中的位置 //设置事件监听 m.addEventListener(ModuleEvent.READY,loadReady);
m.addEventListener(ModuleEvent.PROGRESS,loadReady);
m.addEventListener(ModuleEvent.ERROR,loadError); m.load(); //加载Module
}

3. 加载完毕后将模块添加到Box中,并通过接口调用PictureWindow中的方法setSelectIndex()设置显示的图片。

PictureWindow实现了PictureWindowInterface接口,其中暴露了setSelectIndex方法。再次强调不要直接使用Module对象,如果我们不注意写成 var window:PictureWindow = e.module.factory.create() as PictureWindow,那整个Module就前功尽弃了

//Module加载完成
private function loadReady(e:ModuleEvent):void{
//将Module对象转换为PictureWindowInterface
var window:PictureWindowInterface = e.module.factory.create() as PictureWindowInterface
this.box.addChild(window as DisplayObject);
window.setSelectIndex(1); //通过Interface调用Module中的方法
}

好了,Module的使用就写这么多,看到这里你应该也可以创建自己的Module了,对于ModuleManager和IModuleInfo 中详细的内容,大家可以查阅Flex帮助。

module

源文件下载

5 Comments

  1. idarfan says

    嗯 您的觀念相當的正確.也是一般人較少深入研究的部份,在這兒有兩個問題想跟您請教!
    1. 您在第2部份主程序中点击按钮加载模块PictureWindow
    其中 private var m:IModuleInfo; 已被您宣告為私有變量.
    在底下的程序裏再度被引用. 此時的m 是否是上面那個私有變量的m?
    該怎麼適當的解釋 底下的這個m 所扮演的角色? 這點我以理解.
    是否底下的m 同時是ModuleManager 又具備了IModuleInfo 的機能?

    private function loadModule():void{
    m = ModuleManager.getModule(”PictureWindow.swf”); //设置Module地址,地址是编译后swf在bin中的位置 //设置事件监听 m.addEventListener(ModuleEvent.READY,loadReady);
    m.addEventListener(ModuleEvent.PROGRESS,loadReady);
    m.addEventListener(ModuleEvent.ERROR,loadError); m.load(); //加载Module
    }

    承上例. m.addEventListener(ModuleEvent.PROGRESS,loadReady);
    這行是否有錯誤? 後面調用的方法是否應為底下的方法
    //Module加载中……
    private function loading(e:ModuleEvent):void{
    trace(“显示Loading提示”)
    }
    另外再跟您請教底下這兩行應該如何理解. 或陳述它們的作用
    1.var window:PictureWindowInterface = e.module.factory.create() as PictureWindowInterface
    // 上述的這行代碼. 我的理解是 “變量window實作PictureWindowInterface接口
    其值由e.module.factor.create()引入. as PictureWindowInterface <– 這段不知該做何解釋.
    2. this.box.addChild(window as DisplayObject);
    //上述代碼中,我的理解是 :指向box並新增子元件.而這windows 子元件同時視做DisplayObject)” 這樣理解對嗎?
    3. window.setSelectIndex(0); //通过Interface调用Module中的方法
    //上述代碼中已經調用了PictureWindowInterface 接口.而調用其中的方法
    public interface PictureWindowInterface
    {
    function setSelectIndex(index:int):void
    }
    然而window.setSelectIndex(); 一定得賦值嗎? 不能是null?

    首先感謝您的教程.再次感謝您的回應

    Reply

    Kevin Luo Reply:

    1. m代表IModuleInfo, ModuleManager.getModule(“PictureWindow.swf”);会返回一个IModuleInfo实例,使用这个是来来加载module (m.load()).

    m.addEventListener(ModuleEvent.PROGRESS,loadReady);这里写错了,应该是loading. 谢谢指正。
    e.module.factory.create()是获取加载成功的module, as PictureWindowInterface 是类型转换。 这句话也就是说将加载的module转换为PictureWindowInterface类型(前面说过不能直接转换为module本来的类型,这样会导致module被编译进主程序,这里的PictureWindowInterface就代表PictureWindow,接口里是公开的方法或者属性)。

    this.box.addChild(window as DisplayObject); 将module转换为Displayobject类型,并加入到box里。所有的UI组件都继承与DisplayObject. 只有UI组件才能添加到舞台上(不能将接口作为UI组件),所以我们要做一次转换。这里不管DisplayObject或者PictureWindowInterface都是指代PictureWindow。

    window.setSelectIndex(); 这个当然可以不调,这里只是实例怎么调用moudle里的方法。

    Reply

  2. idarfan says

    您好 感謝您的指教. 在此一同時我在撰寫主程序時發現了一個問題. 茲發文如下
    http://groups.google.com.tw/group/augtw/browse_thread/thread/e7d59940fe7fbb3e?hl=zh-TW%3Fhl
    同時也引用了您的文章. 並註明了出處. 特此通知您一下.

    Reply

  3. Robin says

    这篇文章对我优化程序非常有启发,谢谢!

    Reply

  4. air jordan says

    非常感谢,我的 air jordan网站正好要用这个!

    Reply

Leave a Reply

Leave a Reply
  • (required)
  • (required) (will not be published)