Apache Flex 4.16.1 快速入门与集成示例

用 10 分钟在 Apache Flex 4.16.1 上写出并编译第一个 MXML 加 ActionScript 的 SWF 应用,覆盖 mxmlc 编译验证、file 与 swfdump 产物检查、高频坑排查、Ant flexTasks 集成与 SWC 组件库复用,并给出 RIA 技术选型建议,全部已在 Ubuntu 22.04 实测。

Apache FlexApache Flex2026/10/15

Apache Flex 4.16.1 快速入门与集成示例

目标:10 分钟内在 Apache Flex 4.16.1 上写出第一个 MXML + ActionScript 应用并编译出 SWF,掌握 file/swfdump 两步产物验证;踩平 playerglobal 缺失、locale 中文等高频坑;完成 Ant flexTasks 构建集成与 SWC 组件库复用两个最常用的工程化场景。以下全部命令与回显均已在 Ubuntu 22.04(x86_64)、OpenJDK 1.8.0_504、Apache Flex SDK 4.16.1(build 20171115)实测通过。

一、环境信息

  • 操作系统:Ubuntu 22.04.5 LTS(x86_64)
  • JDK:OpenJDK 1.8.0_504(java -version 实测)
  • 构建工具:Apache Ant 1.10.12(第四章 Ant 集成使用)
  • SDK:Apache Flex 4.16.1(build 20171115),安装于 /opt/apache-flex-sdk-4.16.1-bin,含 playerglobal 32.0(安装过程见 Ubuntu 安装指南篇)
  • 编译产物验证工具:file 命令 + SDK 自带 bin/swfdump
  • 示例工程目录:/root/hello(最小应用)、/root/libdemo(SWC 库)

确认基线(实时回显):

java -version 2>&1 | head -1
mxmlc -version
openjdk version "1.8.0_504"
Version 4.16.1 build 20171115

⚠️ 注意:本文所有 mxmlc 调用假定 PATH 已含 /opt/apache-flex-sdk-4.16.1-bin/bin(配置方法见安装指南篇第七章);未配置时把 mxmlc 换成全路径即可。编译链在 JDK 8/11/17 实测均可运行,但 asdoc 需要 JDK 8,统一基线选 8 最省心。

二、10 分钟最小可用

本节从空目录到编译出第一个 SWF 共 4 步,全程约 10 分钟:建目录写 MXML(3 分钟)→ 编译(1 分钟,首次加载框架库略慢)→ file 验证(1 分钟)→ swfdump 深检(5 分钟)。

2.1 编写第一个 MXML 应用

创建工程目录与 HelloWorld.mxml:

mkdir -p /root/hello

/root/hello/HelloWorld.mxml 全文(最小可用,直接照抄):

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
               xmlns:s="library://ns.adobe.com/flex/spark"
               width="400" height="200">
    <fx:Script>
        <![CDATA[
            import mx.controls.Alert;

            [Bindable]
            private var msg:String = "Hello Apache Flex 4.16.1";

            private function onClick():void {
                var n:int = int(inputBox.text);
                msg = "平方 = " + (n * n);
            }
        ]]>
    </fx:Script>
    <s:VGroup x="24" y="24" gap="10">
        <s:Label text="{msg}" fontSize="18" color="0x1B5E20"/>
        <s:TextInput id="inputBox" text="12" width="160"/>
        <s:Button label="计算平方" click="onClick()"/>
    </s:VGroup>
</s:Application>

逐项说明:

  • <s:Application>:Spark 组件体系的根级可视组件,命名空间 library://ns.adobe.com/flex/spark 由 SDK 内置清单(mx-manifest 等文件)映射到真实类。
  • <fx:Script>:内嵌 ActionScript 3 代码块,[Bindable] 让 msg 变化时自动刷新绑定它的 Label。
  • click="onClick()":MXML 内联事件绑定;onClick() 把输入框文本转成整数并平方,回写 msg。
  • 编译器会把这份 MXML 编译为一个 SWF:入口类是自动生成的 _HelloWorld_mx_managers_SystemManager,这就是 2.3 节 swfdump 里 FrameLabel 的由来。

2.2 编译

cd /root/hello && mxmlc HelloWorld.mxml 2>&1 | tail -2
Loading configuration file /opt/apache-flex-sdk-4.16.1-bin/frameworks/flex-config.xml
/root/hello/HelloWorld.swf (511462 bytes)

不传任何参数时,编译器从默认配置 frameworks/flex-config.xml 读取目标 player(32.0)、SWF 版本(43)、库路径(frameworks/libs 与 libs/player/32.0)等全部设定,源文件名即输出文件名(同目录同名 .swf)。

2.3 验证产物:file 与 swfdump

第一层验证,file 识别文件魔数与版本:

file HelloWorld.swf
HelloWorld.swf: Macromedia Flash data (compressed), version 43

第二层验证,SDK 自带的 swfdump 解析 SWF 内部结构:

/opt/apache-flex-sdk-4.16.1-bin/bin/swfdump HelloWorld.swf 2>/dev/null | head -12
<!-- Parsing swf file:/root/hello/HelloWorld.swf -->
<!-- ?xml version="1.0" encoding="UTF-8"? -->
<swf xmlns='http://macromedia/2003/swfx' version='43' framerate='24' size='8000x4000' compressed='true' >
  <!-- framecount=2 length=1097190 -->
  <FileAttributes useDirectBlit='false' useGPU='false' hasMetadata='true' actionScript3='true' suppressCrossDomainCaching='false' swfRelativeUrls='false' useNetwork='true' brokerProductManager='false' brokerLocalConnection='false'/>
  <Metadata>
    <rdf:RDF xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'><rdf:Description rdf:about='' xmlns:dc='http://purl.org/dc/elements/1.1'><dc:format>application/x-shockwave-flash</dc:format><dc:title>Apache Flex Application</dc:title><dc:description>http://flex.apache.org/</dc:description><dc:publisher>Apache Software Foundation</dc:publisher><dc:creator>Apache Software Foundation</dc:creator><dc:language>en_US</dc:language><dc:date>Oct 15, 2026</dc:date></rdf:Description></rdf:RDF>
  </Metadata>
  <ScriptLimits scriptRecursionLimit='1000' scriptTimeLimit='60'/>
  <SetBackgroundColor color='#FFFFFF'/>
  <ProductInfo product='Apache Flex' edition='' version='4.16' build='20171115' compileDate='10/15/26 7:56 AM'/>

关键信息解读:version='43' 与配置的 target-player 32.0 对应;size='8000x4000' 是 twips 单位(1 px = 20 twips),即 MXML 里的 400x200;actionScript3='true' 确认是 AVM2 字节码;ProductInfo 记录了编译器版本与编译时间。标签里还能看到入口 FrameLabel(续行):

/opt/apache-flex-sdk-4.16.1-bin/bin/swfdump HelloWorld.swf 2>/dev/null | grep FrameLabel
  <FrameLabel label='_HelloWorld_mx_managers_SystemManager'/>
  <FrameLabel label='HelloWorld'/>

2.4 验证点与预期结果

拿到以下结果即编译闭环成功,任一不符按第三章排查:

检查项预期(实测值)不符时排查
mxmlc 退出后产物HelloWorld.swf (511462 bytes) 量级(约 511 KB)报 unable to open 'libs/player/11.1/playerglobal.swc' → 3.1 节
file 识别Macromedia Flash data (compressed), version 43data 而非 Flash → 检查是否编译成功
swfdump 首行version='43' framerate='24'打不开 → 文件损坏或非 SWF
ProductInfoproduct='Apache Flex' version='4.16' build='20171115'版本不符 → 多 SDK 共存时 FLEX_HOME 指错

⚠️ 注意:SWF 无法像 Java 的 jar 那样直接「跑起来看输出」——运行它需要 Flash Player 运行时(浏览器插件已于 2020 年底停止服务)。服务器端的可信验证就是本文的 file + swfdump 组合;需要在浏览器播放存量 SWF 时,用 swfobject 包装页加带 Flash 插件的历史浏览器环境(第四章给出包装页与发布步骤)。

三、快速入门高频坑

以下三个坑在第一次编译 Flex 应用时出现频率最高,均为实测复现。

3.1 坑一:目标 player 版本没有对应的 playerglobal

现象:编译报错(实测回显):

/opt/apache-flex-sdk-4.16.1-bin/frameworks/flex-config.xml(65): Error: unable to open 'libs/player/11.1/playerglobal.swc'

定位:-target-player 指定的版本必须在 frameworks/libs/player/<版本>/playerglobal.swc 有对应文件。本文环境只安装了 32.0。修复:去掉 -target-player 参数使用配置默认值(32.0),或安装对应版本的 playerglobal(下载方法见安装指南篇第五章)。

3.2 坑二:跳过官方安装器导致配置未修正

现象:编译报错(实测回显):

/opt/apache-flex-sdk-4.16.1-bin/frameworks/flex-config.xml(85): Error: unable to open '{playerglobalHome}/32.0'

定位:原始 bin 包里的 flex-config.xml 用 {playerglobalHome} 占位 library-path 前缀,跑过 ant -f installer.xml 后才被替换为 libs/player。这个报错与 JDK 版本无关(实测在 JDK 17 上同样触发)。判断与修复:

grep -c playerglobalHome /opt/apache-flex-sdk-4.16.1-bin/frameworks/flex-config.xml
2

计数大于 0 即未修正;跑安装器或按安装指南篇 5.3 节手工 sed 三个占位值。

3.3 坑三:POSIX locale 下中文日志变问号

现象:编译含中文的 MXML 时,编译器报错回显里的中文显示为问号(实测 <mx:Button label="推送 66.6"> 在错误提示中变成问号),但 SWF 本身的字符串编译是正确的。修复:会话设置 export LANG=C.UTF-8 后重跑,日志恢复正常显示。

四、与 Ant flexTasks 集成

SDK 自带 ant/lib/flexTasks.jar,把 mxmlc 封装成 Ant 任务,并附带 HTML 包装生成器。工程上用它替代裸命令行,实现一次构建出 SWF 加播放页。

4.1 build.xml 全文

/root/hello/build.xml(实测可用版本,直接照抄;路径全部显式写出,便于跨机器复现):

<?xml version="1.0" encoding="UTF-8"?>
<project name="flex-hello" basedir="/root/hello" default="build">
    <property name="FLEX_HOME" value="/opt/apache-flex-sdk-4.16.1-bin"/>
    <taskdef resource="flexTasks.tasks" classpath="/opt/apache-flex-sdk-4.16.1-bin/ant/lib/flexTasks.jar"/>
    <target name="build">
        <mxmlc file="/root/hello/HelloWorld.mxml" output="/root/hello/ant-hello.swf" target-player="32.0">
            <load-config filename="/opt/apache-flex-sdk-4.16.1-bin/frameworks/flex-config.xml"/>
            <source-path path-element="/root/hello"/>
        </mxmlc>
        <html-wrapper title="Apache Flex HelloWorld"
                      width="400" height="200" bgcolor="0xffffff"
                      application="ant-hello"
                      swf="/root/hello/ant-hello.swf"
                      version-major="11" version-minor="1" version-revision="0"
                      history="true"
                      output="/root/hello/wrapper"/>
    </target>
</project>

预建输出目录并构建(html-wrapper 不会自建目录,见 4.2 节坑二):

mkdir -p /root/hello/wrapper && ant -f /root/hello/build.xml 2>&1 | tail -4
Buildfile: /root/hello/build.xml

build:
    [mxmlc] Loading configuration file /opt/apache-flex-sdk-4.16.1-bin/frameworks/flex-config.xml

构建成功的收尾(实测回显):

BUILD SUCCESSFUL
Total time: 3 seconds

核对产物:

ls -l /root/hello/ant-hello.swf && ls /root/hello/wrapper/
-rw-r--r-- 1 root root 511460 Oct 15 08:08 /root/hello/ant-hello.swf
history
index.html
swfobject.js

wrapper/ 里的 index.html 引用同目录 ant-hello.swf 与 swfobject.js,用 SWFObject 做 player 版本探测与嵌入;history/ 是浏览器历史管理辅助文件。

4.2 flexTasks 的两个实测坑

坑一:FLEX_HOME must be set to use the Flex Ant Tasks。 不在 project 里声明 FLEX_HOME 属性直接用 <mxmlc> 时报(实测回显):

BUILD FAILED
/root/hello/build.xml:5: FLEX_HOME must be set to use the Flex Ant Tasks

修复:在 <taskdef> 之前加 <property name="FLEX_HOME" value="/opt/apache-flex-sdk-4.16.1-bin"/>(4.1 节 build.xml 已含)。

坑二:html-wrapper 的 template 属性不存在,输出目录需自建。 给 <html-wrapper> 加 template 属性会报 The <html-wrapper> task doesn't support the "template" attribute.(该任务固定使用 SDK 内 templates/swfobject/ 模板,不需要也不允许指定);且输出目录不存在时报 output directory does not exist: /root/hello/wrapper。修复:去掉 template 属性,构建前 mkdir -p 输出目录。

4.3 本地发布验证

wrapper 目录就是一个可直接发布的静态站点。用任意静态 HTTP 服务验证(实测用 Python 内置服务器):

cd /root/hello/wrapper && nohup python3 -m http.server 8000 >/tmp/httpd.log 2>&1 &
curl -sI http://127.0.0.1:8000/index.html | head -3
HTTP/1.0 200 OK
Server: SimpleHTTP/0.6 Python/3.10.12
Date: Thu, 15 Oct 2026 08:16:39 GMT

⚠️ 注意:SWF 必须与 index.html 同目录(或在 index.html 引用的相对路径上)才可访问。实测把 SWF 编译在 wrapper 之外时,访问 http://127.0.0.1:8000/ant-hello.swf 返回 404(HTTP/1.0 404 File not found);把 ant-hello.swf 复制进 wrapper 后同 URL 返回 200。验证结束记得停掉测试服务(kill %1)。

五、与 SWC 组件库复用

SWC 是 Flex 的库分发格式(一个 zip:catalog.xml 描述清单 + library.swf 字节码)。工程上把通用工具类编译成 SWC,供多个应用通过 -library-path 引用,避免源码复制。

5.1 用 compc 打一个工具库

/root/libdemo/src/com/example/StringUtils.as 全文:

package com.example {
    public class StringUtils {
        public static function isBlank(s:String):Boolean {
            return s == null || trim(s).length == 0;
        }
        public static function trim(s:String):String {
            return s == null ? null : s.replace(/^\s+|\s+$/g, "");
        }
        public static function repeat(s:String, n:int):String {
            return new Array(n + 1).join(s);
        }
    }
}

编译成 SWC:

cd /root/libdemo
mxmlc -version
compc -source-path src -include-classes com.example.StringUtils -output libs/strutils.swc 2>&1 | tail -1
ls -l libs/
Version 4.16.1 build 20171115
/root/libdemo/libs/strutils.swc (2141 bytes)
total 4
-rw-r--r-- 1 root root 2141 Oct 15 08:23 strutils.swc

看一眼 SWC 内部结构(就是标准 zip):

unzip -l libs/strutils.swc | tail -5
---------  ---------- -----   ----
     1224  2026-10-15 08:23   catalog.xml
     1347  2026-10-15 08:23   library.swf
---------                     -------
     2571                     2 files

5.2 应用引用 SWC 并验证类被嵌入

/root/libdemo/SwcUse.mxml 全文:

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
               xmlns:s="library://ns.adobe.com/flex/spark" width="300" height="120">
    <fx:Script>
        <![CDATA[
            import com.example.StringUtils;

            [Bindable]
            private var out:String;

            private function run():void {
                out = "isBlank(空串)=" + StringUtils.isBlank("") +
                      " repeat(ab,3)=" + StringUtils.repeat("ab", 3);
            }
        ]]>
    </fx:Script>
    <s:Button label="Run" click="run()" x="10" y="10"/>
    <s:Label text="{out}" x="10" y="60"/>
</s:Application>

编译时用 -library-path+=libs 把库目录追加进编译期类路径:

cd /root/libdemo && mxmlc -library-path+=libs SwcUse.mxml 2>&1 | tail -1
/root/libdemo/SwcUse.swf (283919 bytes)

用 swfdump -abc 验证 com.example.StringUtils 确实被静态嵌入(编译成功但类没进包是 SWC 引用最常见的假成功):

/opt/apache-flex-sdk-4.16.1-bin/bin/swfdump -abc SwcUse.swf 2>/dev/null | grep -c "com.example"
17

验证点:计数 17(类名、包名与脚本条目多次出现),说明库类随应用一起打进了 SWF;若为 0,检查 -library-path 是否写对目录与 SWC 内包名。注意 -library-path+=libs 中的加号表示「追加」而非覆盖默认库路径,漏写加号会把 framework 系列库全部替换掉导致大片报错。

六、选型建议

Apache Flex 生态内几套发行物各管一段,按需求对号入座:

组件定位本文是否使用适用判断
Apache Flex SDK 4.16.1MXML/AS3 编译器 + Spark/MX 框架库是(全部示例基于它)编译存量 Flash 应用
Apache FlexJS / Royale把 MXML/AS3 编译为 JS 的后继项目否新项目想保留 Flex 开发模式但目标 HTML5
FlexUnitFlex 的单元测试框架否给 ActionScript 代码写测试
BlazeDSJava 后端消息/远程调用网关否需要 AMF 远程通道的存量系统
SWFObject(包装模板)浏览器嵌入 SWF 的 JS 工具是(第四章 wrapper)生成可直接发布的播放页

按场景落到具体建议:

  1. 维护存量 Flash/Flex 工程 → Apache Flex SDK 4.16.1(本文方式,10 分钟出第一个 SWF)。
  2. 新项目但团队只会 MXML/AS3 → 评估 Apache Royale,语法迁移成本低,产物是 JS。
  3. Flash 游戏资产迁移 → Haxe + OpenFL 路线(生态成熟,支持 SWF 资产导入)。
  4. 只需要在页面播放已有 SWF → 不装 SDK,直接用 SWFObject 包装页(第四章 4.3 节的发布方式)。

七、参考链接

  1. Apache Flex 官方主页:https://flex.apache.org/
  2. Flex 4.16.1 发行说明:https://downloads.apache.org/flex/4.16.1/RELEASE_NOTES
  3. flexTasks(Ant 任务)源码与说明(SDK 内 ant/src/flex/ant/ 与官方 Wiki):https://cwiki.apache.org/confluence/display/FLEX/Ant+tasks
  4. SWFObject:https://github.com/swfobject/swfobject
  5. Apache Royale(后继项目):https://royale.apache.org/
  6. SWF 文件格式规范(swfdump 输出各标签含义):https://www.adobe.com/devnet/swf.html