云自无心水自闲

天平山上白云泉,云自无心水自闲。何必奔冲山下去,更添波浪向人间!
posts - 288, comments - 524, trackbacks - 0, articles - 6
  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

其实非常简单, 只需要在application类中定义一个public类型的变量就行了:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
	<mx:Script>
		<![CDATA[
			public var foo:String = "bar";
		]]>
	</mx:Script>
</mx:Application>

在其它的地方就可以使用

Application.application.foo

来访问了. 如果需要, 也可以添加 Bindable 属性.
但是要注意到一个问题就是, 在使用的时候编译器不会进行类型的检查, 因此最好添加类型强制转换.

当然, 全局变量实现的另一种方法是使用单例模式.


posted @ 2007-02-06 13:00 云自无心水自闲 阅读(4836) | 评论 (0)编辑 收藏

有许多方法可以把一个应用拆分成基于个独立下载的部分。甚至于将每个类都分成单独的文件,由ClassLoader在需要的时候加载。但是如果这样效率是比较低下的,因为类的引用有着明显的“引用地域”;如果你引用了一个类,往往会马上牵涉到需要引用一大堆其他的类,如果把这些类全都打包在一起,效率会高得多。

由编译器自动选择一个非常好的打包方法是比较困难的。很可能需要在应用开发时进行一些设定,并不时地监控类的引用。能够统计出最优的分拆方法:应用应该分成几个SWF,哪些类应该放在哪个SWF中。但是这种方法听起来更象是一种研究范畴,实际操作起来非常困难。

让我们来看一些更具有操作性的方法。

很多应用分解后,包含两种类型的功能:“启动后立即填充”和“启动后稍后填充”。

有许许多多的应用是这种模式的。比如:游戏;你有一个游戏引擎和一些游戏场景。或者Portals和Porlets; 一些基础的共享功能和数据驱动的小应用。或者是一个大型的有着1500个页面的保险应用,运行特定功能是只会访问一小部分的页面。或者是充斥大量内容的应用,它可以独立的更新部分内容而不是强制用户每次浏览时都必须下载全部内容。

我称这些相对独立的可以延迟加载的功能为“模块”(Modules),称加载模块的应用为“Shell”。

在这里,我们先不看如何做,先来看一些

shell需要能够与模块交互,同样模块也需要和Shell交互。如果shell引用了modules的一个类,那么它会把它链接进来。同样,如果模块类引用了shell类,它也会把它链接进来。应用能正常运行只有两个方法:或者引用是相同而且共享的(这样就不需要下载两次),或者两者是不同的,而且没有任何关系(尽管两个类名字相同,但是它们被认为是无关的,而且不能交互)。

最好的解决办法是让模块和shell通过接口交互。这样,shell不需要引用模块,而是引用模块会实现的一些接口。同样,模块不实现shell的类,而是允许调用的API接口。

这样在shell变化的时候减少了重新编译模块的次数。具体实现的变化频率往往会比接口本身的变化高得多,而只要接口稳定,就不需要重新编译所有的东西。

注意:需要使用extern(或者extern-library-path)选项来创建模块,这样可以自动剔除shell的类,因为模块是被加载到shell的子应用域中的,将shell的类剔除是安全的。这样模块可以真正直接引用shell中的类。


 

posted @ 2007-02-06 00:05 云自无心水自闲 阅读(1060) | 评论 (2)编辑 收藏

这个例子包括了应用中使用RSL的完整流程。使用命令行进行编译,但是你可以使用FlexBuilder用相同的过程来创建使用RSL。

记住SWC文件是一个包含SWF文件的二进制文件,而SWF文件包含运行时的定义和附属元数据。你可以用压缩工具比如WinZip来打开SWC文件。
在使用RSL之前,首先需要了解如何静态链接一个SWC文件。

在这个例子中,应用有一个app.mxml文件,使用ProductConfigurator.as和ProductView.as。文件目录如下:

project/src/app.mxml
project/libsrc/ProductConfigurator.as
project/libsrc/ProductView.as
project/lib/
project/bin/


编译这个应用时,可以使用source-path选项将/libsrc目录下的类链接进来,方法如下:

cd project/src
mxmlc -o=../bin/app.swf -source-path+=../libsrc app.mxml

这个命令添加ProductConfigurator和ProductView类到SWF文件中。


如果要创建库,可以用compc来创建SWC文件,用下面的命令:

cd project
compc -source-path+=libsrc -debug=false -o=lib/mylib.swc
ProductConfigurator ProductView

注意要将debug选项设置为false. 生成结果是project/lib/mylib.swc文件,包含ProductConfigurator和ProductView两个类。

现在可以使用新创建的库来重新编译应用,用library-path选项来指定库,方法如下:

cd project/src
mxmlc -o=../bin/app.swf -library-path+=../lib/mylib.swc app.mxml

创建库以后,你可以用RSL来重新编译生成应用。完整的步骤如下:

   1. 指示编译器不要将库链接到应用中。
   2. 准备RSL,以便于在运行时使用。
   3. 指示编译器生成附加元数据用于加载RSL。


第一步是指定编译生成应用时库中的哪些类需要排除在外。主要是使用external-library-path选项,如下面的例子所示:

cd project/src
mxmlc -o=../bin/app.swf -external-library-path+=../lib/mylib.swc app.mxml

如果你尝试运行app.swf,Flash Player会抛出一个运行时异常。因为ProductConfigurator和ProductView类还未定义。external-library-path配置选项告诉编译器编译这些库,但是忽略了定义。你也可以使用externs选项,但是一般来说,使用external-library-path更方便。

下一步是准备RSL以便于能在运行时找到它。首先从SWC文件中将library.swf解压出来。

下面是如何解压的例子:

cd project/lib
unzip mylib.swc library.swf
mv library.swf ../bin/myrsl.swf

此例子中将library.swf更名为myrsl.swf,并把它移动到应用SWF文件所在的目录。

最后一步是使用RSL重新编译应用。主要是使用runtime-shared-libraries选项,方法如下:

cd project/src
mxmlc -o=../bin/app.swf -external-library-path+=../lib/mylib.swc
-runtime-shared-libraries=myrsl.swf app.mxml

现在新的SWF文件会在运行应用前动态加载RSL了。

posted @ 2007-02-04 23:36 云自无心水自闲 阅读(1663) | 评论 (2)编辑 收藏

在编译应用时要使用RSL, 需要使用下列编译选项:

    * runtime-shared-libraries 提供运行运行时共享库的位置.
    * external-library-path|externs|load-externs 提供编译时库的位置. 编译器需要这个信息动态链接.


使用runtime-shared-libraries选项来指定SWF文件的位置, 这样应用能够在运行时加载RSL. 需要指定SWF与部署位置的相对路径. 比如: 如果把library.swf文件放在web_root/libraries目录下, 而应用在web_root目录下, 那么文件的指定方法是: libraries/library.swf
可以用这个选项指定多个库. 如果指定了多个库, 需要用逗号分隔.


使用external-library-path选项来指定library在编译时的SWC文件或者目录的位置. 编译器会在编译时根据这个选项进行链接的检查. 你还可以使用externs或者load-externs选项来指定其他单独的classes或者xml文件来定义库的内容.


下面是一个编译MyApp应用的命令行示例, 其中使用了2个库:

mxmlc -runtime-shared-libraries=
../libraries/CustomCellRenderer/library.swf,
../libraries/CustomDataGrid/library.swf
-external-library-path=../libraries/CustomCellRenderer,
../libraries/CustomDataGrid MyApp.mxml

库的顺序非常重要, 因为基础类必须先加载.


你先可以使用配置文件, 示例如下:

<compiler>
    <external-library-path>
        <path-element>../libraries/CustomCellRenderer</path-element>
        <path-element>../libraries/CustomDataGrid</path-element>
        <path-element>../libs/playerglobal.swc</path-element>
    </external-library-path>
</compiler>
<runtime-shared-libraries>
    <url>../libraries/CustomCellRenderer/library.swf</url>
    <url>../libraries/CustomDataGrid/library.swf</url>
</runtime-shared-libraries>


runtime-shared-libraries选项值是library.swf文件是相对部署目录的路径. external-library-path选项是编译时SWC文件的路径. 因此, 必须先知道库的部署路径.

 

示例中, 编译时文件结构如下:

c:/appfiles/MyApp.mxml
c:/libraries/CustomCellRenderer/CustomCellRenderer.swc
c:/libraries/CustomDataGrid/CustomDataGrid.swc

library.swf在编译进不是必需的. Flex编译器不验证SWF文件的存在与否, 但会把路径信息编译进行最后的应用代码中.


文件的部署结构如下:

web_root/MyApp.swf
web_root/libraries/CustomCellRenderer/library.swf
web_root/libraries/CustomDataGrid/library.swf

 

posted @ 2007-02-01 19:17 云自无心水自闲 阅读(1145) | 评论 (0)编辑 收藏

创建库

可以使用Flex Builder或者Compc命令行来创建库. 库可以是一个SWC文件, 或者是包含了library.swf和catalog.xml文件的目录. 一个库通常包含自定义组件和类. 然后就可以在RSL中使用这些库了.

在Flex Bulder中, 通过使用Flex Library Build Path对话框来添加资源到库中.

在命令行中, 使用include-classes和include-namespaces选项来添加文件到库中.

下面的命令行示例说明了如何创建一个名字叫CustomCellRenderer的库:

compc -source-path ../mycomponents/components/local
-include-classes CustomCellRendererComponent -directory=true -debug=false
-output ../libraries/CustomCellRenderer

所有包含的组件必须是静态链接的文件. 使用compc编译器创建库时, 不能使用include-file选项, 因为这个选项不是将library.swf文件静态链接到库中的.

可以使用directory选项指定输出到一个目录而不是到一个SWC文件中:

<?xml version="1.0">
<flex-config>
    <compiler>
        <source-path>
            <path-element>mycomponents/components/local</path-element>
        </source-path>
    </compiler>
    <output>libraries/CustomCellRenderer</output>
    <directory>true</directory>
    <debug>false</false>
    <include-classes>
        <class>CustomCellRendererComponent</class>
    </include-classes>
</flex-config>

输出会是一个目录,目录里包含两个文件
    * catalog.xml
    * library.swf

创建library.swf文件后, 你可以编译应用并且指定文件的位置.

posted @ 2007-02-01 15:25 云自无心水自闲 阅读(725) | 评论 (0)编辑 收藏

UI的问题如何解决呢: AWT, Swing, SWT, 或者是一些其他的比如: Tkinter, WxPython之类的东西?
Bruce认为这些对于创建一个真正跨平台的应用是不够的.
他认为最好的解决方案就是Flex!

Flex and Flash provide a complete, unlimited, flexible tool to build user experiences. From the standpoint of a programmer’s time investment, you can learn a single language for building UIs without worrying about running into problems or limitations later—issues like:

  • Installation problems
  • Constraints on what you can create
  • Sudden steep climbs in the learning curve



原文链接:

http://www.artima.com/weblogs/viewpost.jsp?thread=193593

Computing Thoughts
Hybridizing Java
by Bruce Eckel
January 30, 2007

posted @ 2007-02-01 00:52 云自无心水自闲 阅读(751) | 评论 (0)编辑 收藏

RSL也需要谨慎使用

RSL也不是对于所有的应用都是有益的. 需要对应用RSL前后的下载时间和启动时间都测试过, 才能得到正确的结论.

RSL不能跨域共享. 如果客户在一个域中使用了RSL, 然后运行了另一个域的应用, 虽然这两个RSL是相同的, 但是需要下载两次.

RSL通常会增加应用的启动时间. 这是应用不管整个库实际如何使用, 只是简单地全部加载整个库. 就这一点来说, RSL越小越好. 这与静态链接库的使用是不同的. 当你编译一个Felx应用时, 编译器只解开需要的组件. 一般来说, 库的大小可以是任意的, 它只影响编译时间而不会影响下载的时间.

如果在好几个应用中使用相同的组件库, 那么可以考虑合并这些库, 形成一个RSL. 但是如果库合并后, 每个应用只会用到其中的一小部分, 那么还不如多加载几个小RSL更高效.

如果一些类重复打包在多个RSL中, 那么一定要注意同步更新的问题.

RSL不能应用在基类是Sprite或者MovieClip的纯ActionScript项目中. 因为RSL需要基类知道如何加载RSL, 比如: Application或者SimpleApplication.

关于 framework.swc文件

framework.swc是一个标准的SWC文件. 缺省地它不能用作RSL. 整个framwork.swc文件不被链接到任何一个应用中. Flex编译器只将那些应用用到的部分链接到生成最后的SWF文件. 比如: 如果一个应用只使用了Button, Panel和TextArea控件, 那么只有这几个控件和它们的依赖项被编译器链接.

几乎所有的应用都需要framework.swc文件的一部分, 但是它并不适合作为RSL. 原因如上据说, RSL是整个链接, 不管实际使用多少的. 如果RSL包含了很多类, 而应用只使用了其中的一小部分, 那么这样的加载方式并不是最合理的. 这样使用会造成应用的启动时间大大增加.


RSL的优点

下面的一个例子说明了将几个的共享组件做成RSL的优点. 在这个例子中, 组件库的大小是150K, 编译后的应用的大小是100K.
Application size with and without RSLs 

使用了RSL, RSL只被下载一次. 那么合计下载量是350K, 节约了30%. 如果再添加第3个, 第4个应用的话, 每次都能150K的下载量.

一般来说, 在一个域中使用同一个RSL的应用越多, 那么好处就越大.

posted @ 2007-02-01 00:43 云自无心水自闲 阅读(2165) | 评论 (1)编辑 收藏

理解链接可以帮助你理解RSL是怎样工作的. Flex编译器支持静态链接和动态链接. 静态链接是最通常的方法. 但是动态链接使你借助于RSL来实现SWF文件的缩水以及应用的下载次数.

当你使用静态链接时, 编译器将应用中所有引用的类和依赖生成到最终的SWF文件中, 这个文件会比较大, 下载也会比较慢, 但是下载完毕后, 运行会比较快, 因为SWF文件中已经包含了所有的代码.

如果你的应用中使用了类库, 那么你需要使用类路径或者是添加SWC文件. 如果是使用类路径, 编译器会将类路径中用到的那部分类打包生成到SWF文件中. 如果是使用SWC文件, 编译器会将整个SWC文件打包到SWF文件中.

动态链接是这样的: 一个应用要使用的一部分类存在于一个外部的文件中, 运行时动态加载. 这样的话, 主SWF文件可以小一些, 但是应用依赖于运行时加载的外部文件. RSL就是使用动态链接的.

如果想使用动态链接类, 需要把它们编译成库. 然后编译器将库中的内容从SWF文件剔除出去. 而且必须在编译时提供链接检查.

为指定哪些文件是动态链接的,需要使用外部库路径选项,外部选项或者外部加载编译选项. 这些选项告诉编译器从应用中去除此部分内容, 而预备在运行时调用. 外部选项为动态链接指定了单独的类. 外部加载选项指定了一个XML文件, 描述了动态链接的类.

指定SL的外部资源的顺序是非常关键的, 因为被其他类调用的基础类必须被首先加载.

你还要用runtime-shared-libraries选项来指定RSL的位置.

你可以使用link-report这个编译选项来查看应用的链接信息.

posted @ 2007-01-27 23:42 云自无心水自闲 阅读(746) | 评论 (0)编辑 收藏

减小应用SWF文件大小的一个方法就是将一些共享的外部资源拆分出去, 成为一个独立的文件, 这样可以单独地加载缓存到客户端. 这些共享资源可以由多个应用在运行时进行加载, 但是传递到客户端的动作只会发生一次. 这些共享文件被称为运行时共享库(Runtime Shared Libraries)或者简写为RSL.

如果你有多个应用而且这些应用共享一些核心组件或者类, 那么作为RSL,用户只会唯一的一次加载这些资源. 只要应用在同一个域中, 这些应用共享同一个缓存的RSL, 这样应用文件的大小就减小了. 使用RSL的应用越多, 效果越好, 如果只有一个应用, 总的文件大小不但不减小,反而会增大.

你既可以使用Flex Builder通过项目选项来创建Flex的Library项目,也可以使用compc这样的命令行. 编译好RSL以后, 可以在编译应用时把Library的位置传递给编译器.

下面是适合使用RSL的典型用例:
    * 大型应用, 需要使用通用组件库加载多个小型应用. 最顶级的应用和下级应用可以共享存储在RSL中的组件.

    * 在一个服务器上的使用通用组件库的系列应用. 当用户操作第一个应用时, 用户下载应用的SWF文件和RSL. 当操作第二个应用时, 用户就只需要下载应用本身的SWF文件就行了.
    
    * 一个独立的应用使用RSL的意义在于: 如果这个应用本身会频繁的修改, 而有一部分组件是极少改动的. 在这种情况下, 使用RSL的好处是: 组件下载一次, 而应用可以多次下载.

 

posted @ 2007-01-27 22:52 云自无心水自闲 阅读(974) | 评论 (0)编辑 收藏

总结起来需要注意的原则就是:尽量在编译的阶段发现错误,因为这时发现并解决错误远远要比在运行时出错解决起来容易的多。可是实际情况中很多人经常会违反这一原则,下面是我列举的10个技巧:

1) 永远不要使用'Object' 来存储数据. 因为这是一种绕开编译器检查的做法,完全不符合面向对象的思想。如果要用Hashmap或者相应的数组,那么可以用Dictionary。否则,请自已定义一个类,而不要使用Object来作为数据的存储器。

2) 不要用Object来作为对象的类型。这是欺骗编译器的方法。如果必须这样用,最好在存取属性或者调用函数时,先进行强制性的类型转换,至少这是给编译器的一个提示,也帮助其他人理解你的代码。

3) 也不要用*类型。

4) 不要将ActionScript的类声明为动态。

5) 注意Application.application (和其他的无类型的框架属性). 这个属性有一些古怪.  他应该是Applicaton类型的,因为他指向的实例必须是Application的子类. 但实际上他的类型是'Object', 无法应用编译时的检查。如果你一定要用,最好也进行类型的强制性转换。:

MyApplication( Application.application ).functionCall();

6) 封装你的Xml。使用Xml与Server进行数据的交互非常方便,但是尽量避免使用Xml作为核心数据模型。从服务器收到数据后,尽量把Xml转换为强类型的对象模型。在Flex应用内部使用Xml是绕开编译器的作法。

7) 不要使用DynamicEvent.

8) 不要使用mx:Model。如上所述,请尽量使用自定义的强类型的类.

9) 不要使用Cairngorm中的data属性,而应该继承扩展CairngormEvent来传递数据。

10) 不要把编译器的严格模式关掉

posted @ 2007-01-26 23:58 云自无心水自闲 阅读(986) | 评论 (0)编辑 收藏

仅列出标题
共29页: First 上一页 19 20 21 22 23 24 25 26 27 下一页 Last