chapter 3:application architecture
1、默认情况下,swf文件只能向swf文件所在的域提出http或其它网络请求。如果要仿问swf文件所在的不同的域,即要在目标域的根目录中放置一个crossdomain.xml文件,设置当前服务器接受的域。
?
2、mxmlc可以把mxml、as、swc、rsl等文件打包成一个swf文件,而compc可以把mxml、as等编译成swc或rsl文件。
?
3、部署文件时,请确保rsl等资源文件是否存在于服务器中以及swf文件指向的rsl的路径。
?
4、flashbuilder使用swfobject2类库把swf放在html中。
?
5、在网络安全沙箱内,flash除了ShareObjects外,不能访问本地的磁盘及资源。在得不到用户允许的情况下,不能从摄像头或耳麦中获取信息并发送到网络。
?
6、swf只能访问网络或本地资源两种中的一种。也就是说要么你把swf设置为只能访问网络,要么把swf设置为只能访问本地资源。设置的选项为编译时的use-network=true/false。默认为true。
?
7、flex只持基于组件的开发模型。常规的开发方法是先扩展一些基本的UI组件并把你需要的功能封装在上面,然后再在UI中组装起来。
?
8、在开发过程中,你会使用自已开发的自定义组件或外部的自定义组件。默认情况下flashbuilder在项目src及其子目录下寻找自定义组件。如果你需要使用别的地方的自定义组件,你可以设置source path。flashbuilder除了在src目录下寻找组件外,还会在source path下寻找自定义组件寻找的顺序按source?path顺序寻找。在as中引用组件,使用import语句。在mxml中,使用命名空间。
?
9、swc文件是flex的打包文件,常用的as/mxml通用组件会打包成swc文件。通过library-path可以加载swc文件。
?
10、swf文件被客户端下载后只保存在浏览器的缓存中,浏览器关闭后,swf文件可能会被删除。从swf文件中分离出swc文件以rsl的形式加载可以减swf的体积以及减小每次的下载量。在编译时可以使用runtime-shared-libraries选项指定rsl的位置。
?
11、可以把flex应用分成多个模块(modules)。编译后,原来的一个swf文件变成多个swf文件,主swf文件在需要时才加载或卸载模块。
?
12、在flashbuilder中你可以通过修改配置文件或直接设置command-line argument给编译器。
?
13、flex编译器是区分大小写的。
?
14、swf只能访问自已域保存的ShareObject文件。默认情况下ShareObject的大小为每个域100k。如果要使用大于100k,程序需要弹出询问对话框。另外当大于100k时,fp会自动弹出对话框,询问用户是否允许超过100k的大小。
?
15、fp会自动监控程序占用内存及cpu的情况。如果要长时间占用大量资源,fp会自动询问用户,是否需要关闭应用。
?
16、fp不会把客户端的一些私密信息提供给app,例如:帐户、电话、mail等。但为了提高app的用户体验,fp会提供user agent,系统兼容性(语言,mp3编码),是否有摄像头,麦克风。另外fp还可以设置剪帖板的信息,但不会提供获取剪帖板信息的方法。
?
17、flash有四种沙箱类型。同一个swf文件在不同的沙箱中有不同的安全限制。
?
18、远程沙箱(remote)。所有来自非本地URL的文件(html,swf2html脚本)被放到远程沙箱中。swf按不同的域被分到不同的沙箱中。
?
19、本地文件系统沙箱(local-with-filesystem)。本地文件系统沙箱是本地swf文件的默认沙箱。在此沙箱中的swf文件不能访问远程主机。
?
20、本地网络沙箱(local-with-networking)。本地文件系统沙箱是本地的swf文件具有仿问网络的权限,但不具备访问本地文件的能力。
?
21、本地信任沙箱(local-trusted)。在这个沙箱中的swf没有权限限制。所有本地的swf文件都可以设置成这种沙箱。设置这种沙箱可以通过交互的方式设置(Settings Manager)或能过非交互方式设置(通过安装程置增加配置文件)。
?
22、可以使用编程的方式读取Security中的sandboxType属性查看沙箱类型。
?
23、编译时的use-network参数及swf下载的地方可以决定沙箱类型。本地的swf文件的use-network设置为ture是,沙箱类型为local-with-network,设置为false时为local-with-filesystem。远程下载的swf文件的use-network设置为true时,沙箱类型为remote,设置为false时会报错。
?
24、fp客户端有四种类型。分别为浏览器嵌入式的正式版及调试版和独立版的正式版及调试版。
?
25、fp的浏览器嵌入式客户端在不同的浏览器中以不同的技术实现,在IE中以ActiveX,在其它浏览器中以plug-in实现。在浏览器嵌入式客户端时可以使用一些浏览器技术,例如form及ssl。
?
26、DisableLocalSecurity打开时,swf处于本地信任(local-tursted)安全沙箱中。EnforeLocalSecurity打开时,swf处于其它的三种沙箱中。默认情况下,ActiveX控件是DisableLocalSecurity,plug-in默认为EnforeLocalSecurity。
?
27、交互脚本(cross-scripting)。两个不同的swf文件需要相互访问时需要使用cross-scripting。只有处于同一个安全沙箱中的swf文件才能使用交互脚本。也就是说当swf处理不同类型的安全沙箱,或处于同一类安全沙箱,但swf文件来自不同域时都不能使用cross-scriptin。
?
28、来自不同域的两个swf文件需要cross-script时,可以通过设置Security.allowDomain/allowInsecureDomain方法设置swf文件可以被哪些域仿问。
?
29、flash.net.Externallnterface是调用外部js(call)及设置被js调用接口(addCallback)的主要类。ExternalInterface的调用权限由包装它的html设置,主要参数有:allowScriptAccess和allowNetworking。默认情况下,externalInterface被允许调用同域的js。
?
30、navigateToURL()主要用于打开或替换当前窗口,也可以用于调用外部js。它同样受限于allowScriptAccess和allowNetworking参数的限制。
?
31、由浏览器打开的swf文件以及在swf中的图片相关资源会存放于浏览器的缓存中。这些文件在浏览器关闭后也有可能同样保留在缓存中。所以你可以通过http报头设置当浏览器关闭时清空这些缓存:cache-control:no-cache,no-store,must-revalidate,max-age=-1 pragma:no-cache,no-store expires:-1
?
32、可信任的网页及目录。浏览器本身有一个安全模型。fp会与浏览器的安全模型交互,如果浏览器把一个网页设为可信任的网页,即fp会把该网页下的swf文件处于可信任的安全沙箱(local-trusted)中。另外用户通过fp的User Settings Manager或增加一个FlashPlayerTrust Configuration文件指一个可信任目录,然后把swf文件放到该目录下。当打开该swf文件时,该文件也处于可信任安全沙箱中。
?
33、部署过程中,如果你的swf及资源文件发布在不同的域中。你除了需要增加crossdomain.xml文件以及在app中调用allowdomain等外。最好还需要把一些通配符(*)设置成具体的域和端口。
?
34、fp是区分获取内容(Content)与获取数据(Data)的。Content与Data的区别是Content一般只用于显视,而Data可被as处理。获取内容会比获取数据的限制小一点。在不同域中获取的数据或swf文件会被放到不同的沙箱中。
?
35、向远程读取图片用于显视时,一般不受限制。但从远程读取数据时例如xml时,需要得到远程的授权及html的受权。
?
36、LocalConnection可以让在同一客户端电脑上的各个swf之间进行方法调用。在调用过程中,一个swf称为sender,另一个称为listener。最简单的情况是同一个域中的两个swf之间的调用。在不同域之间调用需要调用LocalConnection.allowDomain()/allowInsecureDomain()方法。
?
37、swf是一种开发格式。所以它可能被反编译,里面的信息会被别人看到。所以发布产品前应该放在里面的敏感信息去调。
?
38、为了做到安全,你应该注意以下几点:一,不要把敏感信息,例如帐户放在swf内。二、用户授权验证、sql等应放在服务端完成。三,如果在使用过程中,swf与server之间传递敏感信息,可以考虑使用ssl。
?
39、安全相关的错误事件并不是由目标对像发出来的。所以并不能用常规的.addEventListener方法去处理错误而是使用try{}catch(e){}方法是铺捉。
?
40、当你使用TextArea或TextInput来输入密码时,请把里面的displayAsPassword属性设置为true。
?
41、在浏览器中打开一个flash后,可以右击-设置。然后对一些权限进行设置。
?
42、模块(Module)是一个SWF文件。它可以被一个或多个app调用,但不能单独运行。
?
43、模块比RSL更灵活。它是否被加载由app决定,并且在编译时不需要被引用。
?
44、模块域(Module Domains)。默认情况下,模块被加载到主app的子域中。这样出现的问题所有模块所在域都从属于主域,但模块间的域就不相同而且没有从属关系。当一个模块调用一些Manager类后,例如(PopoupManager、DragManager),另一个模块再调用这些管理类时将出错。因为那些管理类属于它们被第一次调用的域。要解决这个问题的做法是在主app中,初始化这些管理类,然后这些管理类就可以被各模块共用。
?
45、如果要获取最好的交互性,主app与所有模块最好处于相同的安全沙箱中。
?
46、创建模块的步骤。一、mxml:根元素为<mx:Module>,as:继承Module/ModuleBase。二,像一般应用一样编译它。三、通过<mx:ModuleLoader>标签或ModuleLoader/ModuleManager类去加载模块。
?
47、每个模块都有它自已的IStyleManager2实例,也就是说每个模块都有它自已的样式。各模块之间的样式不会相互影响。在主app加载完模块后,模块的样式会与主app的样式合并,合并的最终结果是模块的样式优先级高于主模块。
?
48、当你在编译模块时使用了isolate-style=false选项时,各模块间将会共用一个样式。如果模块间有相同的样式,即先被加载的样式的优先级会高于后加载的模块样式的优先级。使用该选项后,可能会出现卸载模块后模块不被GC回收等一些情况,因为有些模块的样式可能被其它模块引用。
?
49、getStyleDeclarations()只返回定义的样式,要获取合并后的样式需要调用getMergedStyleDeclaration()。运行间设置样式定义只会影响定义的样式,该样式是否起作用取决于合并样式。
?
50、StyleManager可用于设置所有元素的样式。语法如下:StyleManager.getStyleDeclaration("spark.components.Button").setStyle("fontSize",15);
?
51、模块的开发方法就像app开发方法一样,可以使用mxml或as。模块可以被模块或app加载。
?
52、ModuleLoader提供了高层次的加载接口,而ModuleManager提供了加载模块的底层接口。
?
53、当你的模块要用于显视或用到framework的类,你可以用<mx:Module>标签或继承Module类。如果你的模块不用显视和framework类,你可以考虑用as继承ModuleBase类。这样的模块体积会减小。
?
54、默认情况下Module编译后会包含所有它依赖的类:框架及自定义的类库。结果就是主类加模块的体积远比单独的app大。
?
55、在flashbuilder中可以选择项目-属性-module然后选择模块所属主类,这样flashbuilder可以优化模块的大小。
?
56、当一个模块中的类想用另外一个模块中的类,那就要把模块中的类的模块域提高到app中。
?
57、如果在air中使用模块。那模块必需和主类在同一目录或在主类的子目录中。
?
58、ModuleLoader语法。<mx:ModuleLoader url="com/humanmonth/ColumnCharModule.swf"/>。你需要设置的主要是url。你可以在需要时才设置url,设置后fp才会去加载它。当你设置或重新设置url时会触发ModuleLoader的loadModule()方法,当你把url设置为“”,ModuleLoader会卸载模块。另外你也可以手动调用ModuleLoader的loadModule/unloadModule方法。
?
59、无论你调用多少次loadModule(),fp保证对一个module,一个ModuleLoader只会加载一个实例。
?
60、ModuleManager提供了低层次的加载module的接口。在用ModuleManager加载接口时要注意,module对像要放在类属性中,以免被GC回收。
?
61、如果模块分散在不同的服务器中。你需要解决一些权限问题。Security.allowDomain("remoteservername");Security.loadPolicyFile("Http://remoteservername/crossdomain.xml");new?URLLoader(new URLRequest("http://remoteservername/crossdomain.xml"));loader.load(request);
?
62、把一个app分开多个module的一个好处是主app的尺寸变小了,第一次加载app的时间缩短。但另一个问题是当用户使用到模块时,模块加载也需要时间。解决这个问题的一个途径是预加载模块。预加载模块的
代码:var info:IModuleInfo=ModuleManager.getModule("url");info.addEventListener(ModuleEvent.READY,fun);info.load();
?
63、ModuleLoader就很多事件。你可以扩展它实现自定义的加载类,例如增加一些显视加载进度,图片等效果。让整个系统有一个统一的加载效果。
?
64、通过相关属性引用实现app与module间方法相互调用。这种方法会造成app与module的强耦合和因为代码的引用使得app与module的尺寸增大。但好处是简单直接。方法如下:一,ModuleLoader.child属性。代码:(moduleloader1.child as ChildModule1).fun。二,如果你用ModuleManager加载模块,可以通过以下代码获取模块module.factory.create() as MyModule。三,通过module.parentApplication方法引用父应用。四,模块间调用,先用module.parentApplication得到父应用再调用相应的child或factory属性。
?
65、通过模块的url参数传递数据。 module中有一个loaderInfo属性,里面可以获取调用它的url。你可以从字符串中找到信息。
?
66、模块与app间的相互调用最灵活的方式是让app或module实现自已定义的接口,然后把app或module转型为接口后调用。这样app与module间处于低耦合状态。
?
67、使用子应用(sub-applications)有以下好处:减小主应用的体积;按功能封装代码;增加可重用性;整合第三方子应用。
?
68、对主应用来说,子应用分为可信子应用和不可信子应用。当主应用与子应用基于相同版本的库架构建时具有良好的交互性。如果子应用的库版本较主版本的低,即交互性有一定的限制。
?
69、子应用的可信级别及版本取决于应用域(application domain)及安全域(security domain)。
?
70、有三种类型的子应用:1,单版本应用。2,多版本应用。3,沙箱应用。
?
71、应用域(application domain)是存放类定义的一个容器【类似于java的classloader】。一个应用有一个顶层应用域-system domain。应用域是system domain的一个子域。当你载入一个子应用时,你可以选择把它载入三种域:兄弟域(sibling application domain),子域(child application domain),当前域(current application domain)。
?
72、默认情况下SWFLoader/Loader控件把子应用载到子域中。如果当前应用与子应用所基于的类库版本不同时,载入后会出现错误。如果主与子应用基于不同的库版本,你应该把子应用载入到兄弟域中。
?
73、使用SWFLoader加域子应用时,把loadForCompatibility属性设置为true时,SWFLoader会把子应用加载到兄弟域中,反之,加载到子域中。
?
74、system domain是最顶层的域。共用的域(playerglobal.swc)被加载到此域中。父域已经存放的类定义,子类不会重复加载。
?
75、基于不同版本类库的应用应加载到兄弟域中,否则会出错。
?
76、一般RSL与编译时的资源会被加载到当前域中,SWFLoader一般不会把子应用加到当前域。
?
77、安全域定义了应用的可信级别。多个应用的可信程序越高,它们的交互性越强。
?
78、如果子应用与主应用属于相同域名下载的,默认情况下它们处于同一个安全域。反之,需要设置SWFLoader的trustContent为true让两者处于相同的安全域。
?
79、沙箱应用(sendboxed applications)之间有很多限制。包括不能仿问state对像,不能接收mouse事件,不能调用其它app的画图,不能访问访问其它app的一部份属性。
?
80、大应用、混合编程、一些工具类都会使用子应用的方式加载。
?
81、沙箱应用(sandboxed application)。当你需要加载一些不可信的第三方swf文件,且主swf与子swf所依赖库的版本不一致。这种情况下把子swf以兄弟域的型式加载到主swf中。我们把这种情况叫沙箱应用。
?
82、上面所提及到的所有类型的子应用都应符合条件:主应用依赖的库要比子应用依赖的库新或相同。
?
83、主app加载来自不同域名的子app的情况,我们称为import loading。
?
84、采用模块与子应用有以下区别:因为模块与主应用共享类定义,所以文件尺寸会小一点。模块与主应用的耦合性高一点。模块与 主应用要使用同一版本的库而子应用没这个要求。模块一般会在主应用的子应用域中,所以管理类共享。模块只能加载到主应用的子应用域中,而子应用可以载进主应用的兄弟应用域或子域。模块只能放进安全模,而子模块既可放进安全域也可放进不安全域。
?
85、SWFLoader与Loader的区别。SWFLoader是Loader上的一个封装,使用起来更简单,且提供了一些额外功能,例如支持样式与效果,可以监控加载进度,被加载的swf文件可以是多版本的。
?
86、夸域交互时,建议采用事件机制进行。
?
87、沙箱应用与多版本应用在编译时应加上以下参数:-include=mx.managers.systemClasses.MarshallingSupport。
?
88、子应用可以独立运行。它不应依赖主应用以及兄弟应用。
?
89、设置SWFLoader时可以单独设置loadContext或直接设置loadForCompatibility和trustsContent。loadContext的优先级要高于后者。以上属性应SWFLoader加载前设置。
?
90、LoadContext对像有两个属性,一个为securityDomain另一个为applicationDomain。如果不设置securityDoamin时,子应用会采用它自已的的安全域。如果要把子应用设置成可信域,即使用以下语句:context.securityDomain=SecurityDomain.currentDomain。设置applicationDomain时可以设置三个值:new ApplicationDoamin():兄弟域,new ApplicationDomain(ApplicationDomain.currentDomain):子域。application.currentDomain:当前域。最后要注意的是同一个LoadContext不要用于加载多个应用。
?
91、卸载子app时可以使用loader.unloadAndStep(true)或loader.source=null。另外,当loader再load一
?
个子app时,上一个app会被自动卸载。
?
92、在可信任的单版本的子app中,子app可能通过application或parentDocument访问主app。
?
93、主app访问子app的方法:(contentLoader.content as SystemManager).application as SubApp2。
?
94、如果主应用要加载子应用中的类,那子应用一定要和主应用处在同一个安全域及相同的版本。加载的方法为new UIComponent(new (loader.loaderContext.applicationDoamin.getDefinition('ClassName')?as Class)());。访问相关属性 obj['property']。?
?
95、在sandboxed application中,除了FocusManager外,其它的Manager,例如DragManager、ToolTip、Alert、指针等的效果都只在子app中出现,主app不受这些效果的影响。
?
96、相同安全域的主从应用可弹出框、ToolTip、鼠标不限于子应用区域。
?
97、Bootstrap 是一个轻量级的类容器。它先于主应用被加载,所以由它加载的类可以在各应用在共享。一般情况下,一个安全域可以用一个bootstrap。因为bootstrap加载的类不能在不同的安全域间共享。
?
98、如果子应用需要使用rpc,那rpc相关类一般会由Bootstrap加载。
?
99、BABridge(Flex Ajax Bridge)是一个简单的类库,用于js与as间的相互调用。利用ExternalInterface类也可以实现相关功能,但需要编写复杂的代码及限制比较多。
?
100、BABridge的地址在sdk_installation_dir/frameworks/javascript/fabridge下。如果你使用FlashBuilder,你可以直接右击项目,选择:Create Ajax Bridge。你需要在mxml中加入<fab:FABridge?xmlns:fab-"bridge.*"/>。完成后,你就可以在js中直接使用FABridge.flash.root()引用flash的主类。
?
101、获取加载swf人url人代码:mx.core.FlexGlobals.topLevelApplication.url。
?
102、获取客户端信息的类:flash.system.Capabilities。从中可以获取客户端操作系统,播放器,语言等。
?
103、ExternalInterface是as与js互相调用的主要类。其中主要方法有两个:call()/addCallback()。ExternalInterface受安全沙箱的限制,它受限于swf的引入代码中allowScriptAccess/allowNetworking属性的值。
?
104、在初始化阶段,我们一般需要向swf文件传一些参数。我们可以通过htmlwraper中的flashVars、swf的url参数、swf初始化后通过ExternalInterface调用js获取页面中的参数。三者相比,通过url传参比较简单。
?
105、通过静态方法ExternalInterface.call(funName,para... paras)调用js。
?
106、flash.net.navigateToURL()可用于调用js,也可用于打开新窗口。
?
107、URLLoader用于后台向服务器发出请求,而navigateToURL()用于调用浏览器的窗口加载页面。
?
108、navigateToURL(req:URLRequest,window:String)用法。window的值所代表的意思:_self:在本窗口打开,_blank:本窗口之上弹出,_parent:在父窗口打开,_top:最顶层窗口打开。
?
109、navigateToURL调用js:navigateToURL(new URLRequest("javascript:fun()","_self");
?
110、在swf的html包装器中allowScriptAccess的选项有三个:never,sameDoamin,always.
?
111、一些公用的类加、资源可以打包成RSL(Runtime Shared Libraries)。RSL被下载到客户端后可以被多个应用共享使用。
?
112、有三种类型的RSL:Framework:官方标准库,可被任意应用使用。Standard:自已打包的应用,可被相同域的应用使用。Cross-domain:在Standard的基础上可被任意域使用。Framework与后两者的另一个区别在于签名的Framework(swz)存放在fp相关目录下,而后两者存放在浏览器的缓存中。另外要注意的是非签名的framework(swf)也存放在浏览器缓存中。
?
113、flex编译时分静态链接与动态链接两种。如果使用静态链接,flex在编库时把相关库和应用打包成一个文件。静态链接的特点是文件很大。与静态链接相关的编译参数为有四个library-path,include-libraries,includes,source-path。前面四个参数中包含include关键字的参数是把关联的所有库打包进主应用中,而没有include的是把相关联的类打包进主应用中。动态链接是让应用在需要用到相关类时才加载。模块、运行时样式表、RSL都使用动态链接技术。在flash builder中你可以从Project-Properties-Flex?Build Path-Library Path中 设置link Type。
?
114、使用动态链接时,需要在编译中加入参数:runtime-shared-library-path,runtime-shared-libraries,external-library-path,externs,load-externs。
?
115、sdk/frameworks/libs下以swc结尾的库为编译时使用的。sdk/frameworks/rsls下以swf结尾的为unsign库,swz结尾的为sign库。
?