编辑
抱歉,我没有注意到您不想支持不同版本的库。在这种情况下,没有办法——当 FP 处理 SWF 的字节码并找到未知引用时,它会抛出 VerifyError。当然,你可以使用getDefinitionByName()
和动态访问,但是它很慢。
为了最大限度地减少单独支持的代码量,您可以使用具有主要功能的 SWC 和具有版本相关功能的 SWF,因此在初始化阶段,您的 lib 的主类将检查 FP 版本并加载适当的 SWF。
这称为动态链接,有一种方法:
创建所有播放器版本相关功能的接口 ( public interface MyInterface...
)。此接口不应包含对版本相关 API 的任何引用。将此接口(它可能只是单个 .as 文件)编译成 SWC(顺其自然lib-intf.swc
)。
创建此接口的两个独立实现;第一个将使用新的 API,第二个不会(它可能只是一个占位符,但也可能是一个替代实现)。稍后我们需要将这些实现编译成 SWF,因此我们需要扩展Sprite
. 最简单的方法是让这些主类实现我们的接口(即public class MyImplementationA extends Sprite implements MyInterface...
和 相同MyImplementationB
)。它们只是空Sprites
的,但它们将包含接口方法。
将这两个实现独立编译成单独的 SW F (lib-a.swf
和lib-b.swf
)。编译时,lib-intf.swc
作为外部库包含(-external-library-path
编译器参数或 IDE 中的“外部”链接类型)。
现在,在编译根应用程序时,lib-intf.swc
像往常一样包含库(-library-path
编译器参数或 IDE 中的“合并到代码”链接类型)。根本不包括与版本相关的类。因此,在根应用程序中,您将只引用与版本无关的接口。当您的应用程序启动时,检查 FP 版本,并根据它使用 Loader 类加载适当的 SWF。您必须将其加载到主应用程序域中,而不是它的子域(这是默认选项;更多详细信息)。
加载 SWF 后,将其转换为界面:var versionDependentImpl:MyInterface = loader.content as MyInterface
. 请记住,我们的 SWF 的主要类实现了MyInterface
,所以这个转换可以工作。
就是这样——现在你可以使用你的实现了:versionDependentImpl.someMethod()
. 当然,someMethod
应该定义在MyInterface
.
因此,这里的技巧是从 SWF 文件动态加载实现。虽然根应用程序对这个 SWF 中的类一无所知,但我们可以使用它的主类的方法,因为我们让它实现了一个我们已经编译到根应用程序中的接口。
这种方法是可扩展的:例如,您可以定义具有返回其他接口的方法的主接口。您甚至可以将实现之间共享的具体类包含到lib-intf.swc
中,只要它们不使用与版本相关的 API。