使用Adobe AIR构建插件体系结构

时间:2008-12-05 18:12:38

标签: flash air flex3 dynamic-loading plugin-architecture

我正在考虑选择Adobe AIR作为即将推出的项目的客户端实现技术。 (之前的选择是C#和WPF,但最近我对Flash / Flex / AIR印象非常深刻。)

但我的产品最重要的功能之一将是其插件架构,允许第三方开发人员以有趣的方式扩展功能和GUI。

我知道如何在C#中设计架构:插件加载器将枚举本地“app / plugins /”目录中的所有程序集。对于每个程序集,它会枚举所有类,寻找“IPluginFactory”接口的实现。对于工厂创建的每个插件,我会询问它的MVC类,并将其GUI元素(菜单项,面板等)捕捉到现有GUI布局中的相应插槽中。

我想在AIR中完成同样的事情(从本地文件系统加载插件,而不是从Web加载)。阅读this article之后,我的理解是可能的,并且基本架构(将SWF加载到沙盒ApplicationDomains等中)与您在.NET中的方式非常相似。

但我对这些陷阱感到好奇。

如果您有任何人使用Flash播放器进行任何动态类加载(最好是在混合flash / flex应用程序中,并且特别是在AIR主机中),我很想知道您构建插件框架的经验以及运行的位置使用Flash播放器以及flash,flex和AIR API处理棘手的情况。

例如,如果有人问我同样的问题,但考虑到Java平台,我肯定会提到JVM没有“模块”或“程序集”的概念。最高级别的聚合是“类”,因此在插件系统中创建用于管理大型项目的组织结构可能很困难。我还将讨论多个类加载器的问题,以及每个类加载器如何维护自己独立的加载类实例(具有自己独立的静态变量)。


以下是一些尚未解答的具体问题:

1)actionscript“Loader”类可以将SWF加载到ApplicationDomain中。但该appdomain究竟包含什么?模块?类? MXML组件是如何表示的?如何找到实现我的插件界面的所有类?

2)如果您已将插件从主应用程序加载到单独的ApplicationDomain中,那么从其他应用程序域调用代码会更加复杂吗?关于可以通过app -main域间编组层的数据类型是否有任何重要的限制?编组是否过于昂贵?

3)理想情况下,我想将自己的大部分主代码作为插件开发(主应用程序只是一个插件加载shell)并使用插件架构将该功能提升到应用程序中。这会让你害怕吗?

4 个答案:

答案 0 :(得分:6)

  1. applicationDomain更像是命名空间,它将类定义分组并将它们放入层次结构中:域可以直接访问其自己的域或父域中的符号,但在子域中或兄弟域(或更好:它不能直接执行 - 它必须通过applicationDomain对象,询问给定类的定义);加载外部swf时,您可以决定 where 以放置新符号:子域(默认),附加到系统的新域(使用null),当前域,一个附加在其他地方的域(显式传递新域的父域)。请注意,新符号永远不会覆盖当前域中的符号,但多个域中可能存在相同的名称 不幸的是你不能枚举给定域中的类(好吧,至少我不知道有什么方法可以做到),但常见的解决方案是要求(如“插件接口”中)知名的存在每个swf中的工厂,它将返回插件的定义(Class)或插件本身。
  2. 你只是以某种方式获得对象的引用(工厂),然后它只是另一个对象。没有编组:域只是命名空间的逻辑分区(它是系统域的树分支)。
  3. 否:)但是要注意:它可能很容易变成GC的地狱,由于引用在其他域中传播,因此无法卸载未使用的域。我建议看看多核PureMVC框架,可能还有管道,以确保插件之间的严格分离。
  4. Btw,Flash Player也是一个安全域的概念,但我实际上从未触及它,所以我不知道这里有什么可能性。

答案 1 :(得分:5)

Luca Tettamanti已经对您的具体问题给出了很好的答案,所以我只提供一些关于一般主题的其他信息:

我使用ModuleManager类(以及mx.modules包中的其他内容)为Flex应用程序实现了一个简单的插件API。)它的要点是你从{{继承插件1}}并在主机应用中使用ModuleBase加载它们。然后你让插件实现一个通用接口(例如ModuleManager)并使用某种facade来表示和实现插件可以使用的主机应用程序的接口(例如IMyAppPlugin 。)每当加载插件时,将此外观引用注入其中。

Flex 3帮助中的主题"Modular applications overview"有一些很好的信息(子章节“模块域”在模块的上下文中讨论应用程序域。)以下是摘录:

  

“默认情况下,模块会加载到当前的子域中   应用领域。你可以指定一个   使用不同的应用程序域   的applicationDomain属性   ModuleLoader类。“

主题"Using the ApplicationDomain class"更深入地讨论了应用领域的主题,如果你还没有,你一定要阅读它。

答案 2 :(得分:0)

回应关于Java作为可能的插件架构的声明:

事实证明,Java已被用于设计插件架构系统多年。至于客户端,Equinox OSGi模块管理框架可能是最知名的。有一次,Eclipse IDE在Equinox OSGi之上重构了他们的插件架构。 Eclipse IDE可能是迄今为止最成功的客户端插件架构系统之一 - 从历史长寿的角度来看,以及用户群的广度和插件开发的后续社区。他们还提供插件架构作为设计任意客户端应用程序的基础框架 - Eclipse RCP。

我只是插入这个因为尽管Java被定位为可能是一个非常弱的选择,但它实际上比任何其他语言/运行时环境在提供此类工作系统方面要成功得多 - 特别是对于C# .NET,当然,它具有很好的模块固有功能。有点讽刺,但你有它。

对于Adobe AIR,我正在管理一个正在AIR上设计的项目。在我们的例子中,我们的模块可扩展性总是从Web服务器传递 - 而不是本地目录。

<mx:Module/>

用于创建可在运行时离散加载的模块的标记。

唉,对AIR的沮丧是缺乏用于启动其他应用程序的任何类API。您可以加载URL以在用户的​​默认浏览器中加载某些内容,但是您无法启动Excel。 Java和C#都有用于启动其他应用程序作为外部进程的API。

答案 3 :(得分:0)

您是否尝试过加载子应用程序?
在AIR中有很好的文档,我在几个小时内就成功了。但是,由于子应用程序和主应用程序之间的沙箱冲突,Flex中的相同实现是不同的故事。我花了几个星期的时间撞到了墙上。