DarkStone - 跨平台移动应用开发之 Flex 的崛起

时间:2022-12-27 23:22:32

我的好友Ds 发布一个flex的消息.我帮忙转发

DarkStone - 跨平台移动应用开发之 Flex 的崛起

(2013-08-20 22:28:32)

 

此文章由 周戈 (DarkStone) 原创, 发表日期 2013-08-19, 转载请注明来源:

微博: http://weibo.com/dstech

博客: http://blog.sina.com.cn/dstech

QQ群: 23477140

欢迎各位 ActionScript 同仁的大驾光临, 我今天发布的消息非常振奋人心, 为此我这几天非常亢奋, 热血沸腾.

开始前我先问大家两个问题:

一个好的游戏能被玩多久? 几个月或者一年已经打破天了.

一个好的应用能被用多久? 几年或者十几年也很常见.

不适合阅读本文的读者: 打算用 AS3 开发 2D/3D 游戏的相关人员.

AS3 开发移动平台游戏目前我还是推荐用:

Starling + Feathers UI + Firefly + Away3D

因此如果你是这个范围的人, 就不用浪费时间继续阅读下去了.

适合阅读本文的读者对象: 打算用 AS3 开发除游戏以外跨平台跨设备应用的相关人员.

对于那些懒得看完全文的人, 这是我的一句话中心思想:

Flex 技术从现在开始重新崛起, 成为跨平台跨设备最高开发效率, 最易后期维护, 最佳的应用开发解决方案, Flex 开发者身价将重新暴增.

我本次演讲主要分3部分:

1. 重大发现: Flex 4.10 + AIR 3.8 在 iOS 和 Mac 平台的执行效率已接近 PC!

2. 为什么 Flex 是跨平台跨设备的最佳应用开发解决方案?

3. 新手如何使用Flex, 以及开发移动应用要注意的问题.

1. 重大发现: Flex 4.10 + AIR 3.8 在 iOS 和 Mac 平台的执行效率已接近 PC!

经过我在 iPhone 4, iPhone 5, iPad 3 和 Retina MacBook Pro 的亲自实测, 我很高兴的向大家宣布:

Flex 4.10 + AIR 3.8 在 iOS 和 Mac 平台的执行效率已经接近 PC, 达到了一个里程碑的层次!

在 iPhone 4, iPad 以前(也就是 2010 年以前), PC 还是主流的时候, Flex 是 PC 平台最高效率的应用开发组件框架.

但在 iPhone 4, iPad 出现之后, Flex 虽然可以在上面运行, 但执行效率很低, 跑起来非常卡, 后来 Adobe 把 Flex 捐献给开源社区 Apache 来维护, 于是 Flex 技术从它的巅峰时代直接滑落至谷底.

然而就在 Flex 开发者面临窘境, 进退两难的时候, 惊喜终于出现了! 最新的 Flex 4.10 + AIR 3.8 经过我这2天的实测, 性能从根本上得到了提升, 即便是在 iPhone 4 这样低配单核的机器上也能较流畅地运行, 在 iPhone 4S, iPhone 5 和 iPad 3 上运行则非常流畅.

我将我们自行开发的产品做成 demo, 就在今天上午, 我当着所有同事的面, 演示了我们的产品在 Windows, Mac, iPhone 4, iPhone 5, iPad 3 上的运行效果, 大家一致认为很理想, 完全适用于产品级开发!

2. 为什么 Flex 是跨平台跨设备的最佳应用开发解决方案?

首先, 选择跨平台的技术, 可以极大提高产品开发效率, 降低维护成本, 这块的好处大家都知道, 那么目前主流的跨平台技术, 我为大家分析下利弊.

先来看HTML5 + JS +CSS3 + SVG (以下简称H5):

未来的 Web (浏览器领域)属于H5, 而Flash Player 这样的浏览器插件正在走向灭亡, 比如在移动设备的浏览器上 Flash Player 就已经死了.

虽然 H5 会统治整个 Web, 但我们现在回头看看整个IT市场:

◇ 现在PC已经不是主流设备.

◇ 现在的主流设备是移动设备, 比如智能手机, 平板电脑, 还有智能腕表 和 智能眼镜等.

那么, 在 PC 时代已经衰落接近底谷的今天, 我们作为开发者, 重点应该放在长远, 更有活力, 更有前景的移动平台.

我们就谈谈现在主流的移动平台:

◇ 在移动设备上 B/S 架构的 Web 浏览器应用不是主流, 也成不了主流.

◇ 在移动设备上 C/S 架构的本地应用才是主流, 大家可在移动平台的应用商店下载和购买很多本地应用和游戏, 但没有人会去浏览器里购买网页的应用.

因此核心点在于我们需要一门跨平台跨设备并且适合开发本地应用的技术, 显然 H5 完全不适合担当这个角色, 原因:

◇ 第一, HTML5 + JS 这些语言没有考虑本地应用的需求, 它们原生的 API 无法直接调用各个平台私有的功能, 比如 iOS 的 GameCenter, iCloud, Push Notification, Passbook 等等, 这会导致你想做的很多需求无法轻易做出来. 而这个问题从长远来讲也不大可能得到解决, 因为如果 H5 可以随意调用系统的私有 API, 那么整个互联网将更不安全, 现在的网页病毒已经够多了, 试想如果用户进一个网页, 网页有权限把用户的文件资料全部删除, 那是什么概念).

◇ 第二, JS 1.x 不是面向对象的脚本语言, 用于团队开发大型项目就是个噩梦, JS 2.0 虽然会完全面向对象, 但也迟迟没有要发布的消息.

◇ 第三, H5 的开发调试得在N个不同厂商的浏览器上分别测试, 浏览器厂商对 H5 标准的实现各自有所不同, 这个一直是 Web 开发人员相当头疼的问题.

那么到底哪门技术才是跨平台跨设备的最佳应用开发解决方案呢?

以前的答案是: 还没有(因为以前 Flex 在移动平台执行效率很低).

现在的答案是: Flex! Flex! Flex!

以前在移动平台上 AIR 虚拟机对 ARM 芯片和 iOS 系统的优化程度做得很差, 导致其 CPU 执行效率很低, 于是诞生了 Starling, Feathers UI, Firefly 等这类第三方基于 GPU 执行的框架来解决 AIR 在移动设备上的性能问题.

但从 AIR 3.8 起, AIR 虚拟机对移动平台 CPU 的执行效率, 相比以前我看到了天与地的区别. 如果你还在为自己是一个 AS3 开发者感到迷茫, 甚至有些人觉得要转行, 觉得没搞头, 那么在 AIR 3.8 以前确实如此, 但现在这个格局已经彻底改变了.

现在仔细谈谈 Flex 的组成: AS3 + MXML + CSS + FXG

◇ AS3 用于编写逻辑层 (开发人员负责) 优势: 强类型面向对象语言, 利于团队开发.

◇ MXML 用于设计皮肤层 (设计人员负责) 优势: 快速布局应用皮肤, 强大的数据双向绑定, 面向体验的语法设计, 高级皮肤状态绑定, 高度的可扩展性, 众多的内置组件可用, 可迅速搭建应用程序原型.

◇ CSS 用于编写样式表 (设计人员负责) 优势: 在统一的地方管理所有界面的样式属性, 利于高效率的维护界面样式, 高效率的切换整套界面皮肤.

◇ FXG 用于可复用的矢量素材 (设计人员负责) 优势: 用 XML 语言来描述矢量图形, 具有高度的可读性, FXG 可直接放在 MXML 里当做标签使用, 具有极其强大的可复用性和可扩展性.

Flex 的 MXML 类似 xHTML. Flex 的 CSS 类似 Web 网页的 CSS. Flex 的 FXG 类似 Web 网页的 SVG. 因此除了 AS3 本身比较专业以外, 其它环节相对容易, 完全可以培训设计人员来分工.

除此以外, Flex 的重要特性还有:

◇ 内置大量桌面和移动平台的常用组件, 比如 Button, CheckBox, Panel, ViewNavigator, SpinnerList 等等.

◇ 组件的 逻辑层 和 皮肤层完全分离, 这样开发人员可来写逻辑, 同时设计人员去做皮肤, 工作效率不言而喻.

◇ 一个 Flex 应用可同时部署到 Windows, Mac, Linux, iOS, Android 全平台上, 还能部署到桌面系统的浏览器里. 如果需要调用系统私有 API 则可使用 ANE 做本地扩展(非常强大)!

◇ 用 Flex 部署的应用, 可根据目标设备屏幕的 dpi 自动缩放自身界面的元素大小以达到最佳效果, 只需要将矢量素材做成 FXG, 在一个屏幕下完成正确的布局, 就可实现在其它 dpi 屏幕下的界面自动缩放, 而不用为了不同 dpi 的屏幕来制作不同尺寸的相同素材.

好, 给点时间大家先提问, 还有一个代码环节我将放在后面.

Q&A:

Q: MXML 写组件皮肤? MXML有计划瘦身吗?

A: MXML 的优化关键在于编译器, 所有的 MXML 都是由编译器转换为 AS3 的类文件, 编译器转换过程中的算法很重要, 它将决定 MXML 到 AS3 的代码量和性能, 这一块目前已经做得比较好了, 从编译速度来看, 较以前有一定的提升, 间接可以感觉到编译器的改进.

Q: 现在有几个设计人员管你这些... 我遇到的设计基本上就是给你做个 UI 图然后就交给你了.

A: 那是你们公司分工和培训有问题. 我前后带过3个团队, 都是培训美工写 MXML 和 CSS 还有 FXG 的, 培训成本并不大, 边做边学2周左右就会了.

Q: 素材在 Flex 里是如何管理的, 需要为不同 dpi导出不同尺寸的相同素材文件吗?

A: 我来谈谈关于素材这一块的问题:

一旦你开始做移动应用, 你面临的将是不同目标设备, 不同屏幕的 DPI 像素密度, 如果你的目标屏幕有 160 dpi, 264 dpi, 326 dpi, 480 dpi 等, 那么你要是用 Photoshop 做的话, 同样的一个小图标, 你就得为这些 dpi 导出不同尺寸的版本.

那么, 一般的项目都会有上百个素材, 假设有100个图标, 你就要导400个文件出来, 这样的开发成本太高了, 效率太低了.

而如果大家把能用 Flash / AI 做的素材, 转成并优化成 FXG 格式, 再放到 Flash Builder 里面, 就可以在 MXML 里当做一个标签来使用, 复用性极强, 每个 FXG 其实就是一个 Class 类, 类的复用性强大家都知道吧.

然后, 在 Flex 里, 有 applicationDPI 可以设置(不过目前 RuntimeDPIProvider 有个小 bug), 用它就可以为不同的 dpi 自动缩放整个界面的元素:

换句话说, 假设你做了100个图标素材, 你只需要把这100个图标素材做成 FXG 格式, 然后布局到你的 MXML 里, 接下来正确设置你的 applicationDPI 和 runtimeDPIProvider, 你就可以不用再改代码, 不用再改素材尺寸的情况下, 支持所有不同分辨率, 不同 DPI 的设备, 仅这一点, 工作效率已经是最高的了!

我今天上午给公司内部看的 demo 就是典型的例子:

我们在 PC 上设计整个应用的界面, 用 FXG MXML 布局, 这些界面和素材都是在 160 dpi 的屏幕上做好的, 而我轻易就把这个应用移植到了 264 dpi 的 iPad 3 上, 和 326 dpi 的 iPhone 4 / iPhone 5 上, 还移植到了 220 dpi 的 Retina MacBook Pro 上, 并且效果都很完美, 完全没有失真.

Q: 界面被放大后会不会模糊?

A: 注意, 这样放大后, 完全不会模糊, 因为:

只要所有素材都是用 Flash / Ai 做出来的矢量图, 矢量图放大缩小是不会失真的, 将其转成 FXG 之后, FXG也是矢量的, 更易于复用和维护. 其实放大后的 UI 在视网膜屏幕上反而更加清晰透彻, 看着很舒服.

Q: 问题来了, 矢量图是已知的 CPU 杀手, 如果应用中不使用位图, 请问为什么很多项目都需要导出位图来改善渲染性能? 用 PS 导出位图的目的就是为了不使用矢量图.

A: 这也是我代码要讲的, 矢量图可以动态缓存成位图来解决性能问题的, 等下我会仔细讲的.

如果你用 PS 导出位图, 那么你就要为不同 dpi 导出不同尺寸的位图.

如果你用 FXG, 它本身是矢量的, 高可读性的, 1个素材只用导出1个FXG, 然后 Flex 根据设备屏幕的 dpi 动态放大所有矢量 FXG, 以保证清晰, 不失真, 同时, 你可利用 DisplayObject.cacheAsBitmap = true 将需要频繁位移的显示对象进行动态缓存, 将矢量图缓存成标量图, 从而一定程度上提高性能, 注意这个方法不能滥用, 滥用反而会导致性能下降.

Q: 请问cacheAsBitmap能提升多少性能? 我在byteArray.org上看到性能很低, cacheAsBitmap在Adobe官方工程师的测试, 会卡到 8 FPS.

A: cacheAsBitmap这玩艺不能瞎用, 要善用, 后面我会仔细讲的. 况且 byteArray.org 上的测试是在 2008 年做的, 用的 playerglobal.swc 也是很旧的版本来编译的, 还有测试环境是 Flash Player 而不是 AIR 3.8.

Q: 我想知道您是怎么测试的, 能把测试代码公布下吗?

A: 我现在手上有的 demo, 是自己公司正在开发的产品, 不方便泄露, 但我有空可以开发一个能证明我今天所说的一切的 demo, 到时候会提供安装版的下载.

3. 新手如何使用Flex, 以及开发移动应用要注意的问题.

好, 接下来先手把手教大家怎么搭建 Flex 4.10 + AIR 3.8 + Flash Builder 4.7 的开发环境.

先请大家收藏 Apache Flex 官方网站 http://flex.apache.org/.

去这个页面把 Flex 4.10 的安装器下载下来, 安装到你的机器上http://flex.apache.org/installer.html

- 跨平台移动应用开发之 Flex 的崛起" name="image_operate_86321377011771391" alt="DarkStone - 跨平台移动应用开发之 Flex 的崛起" src="http://s16.sinaimg.cn/mw690/6f56a2bfgx6C0F2xjY3cf&690" width="298" height="298" real_src="http://s16.sinaimg.cn/mw690/6f56a2bfgx6C0F2xjY3cf&690">

安装好后运行 Apache Flex SDK Installer, 看到这个画面, 不用修改, 直接 NEXT.

- 跨平台移动应用开发之 Flex 的崛起" name="image_operate_78031377011793797" alt="DarkStone - 跨平台移动应用开发之 Flex 的崛起" src="http://s10.sinaimg.cn/mw690/6f56a2bfgx6C0FbJuPv19&690" width="690" height="624" action-type="show-slide" action-data="http%3A%2F%2Fs10.sinaimg.cn%2Fmw690%2F6f56a2bfgx6C0FbJuPv19%26690" real_src="http://s10.sinaimg.cn/mw690/6f56a2bfgx6C0FbJuPv19&690">

这时在你的 Flash Builder 安装目录的 sdks 目录里新建一个叫 4.10.0 的文件夹.

- 跨平台移动应用开发之 Flex 的崛起" name="image_operate_78691377011852777" alt="DarkStone - 跨平台移动应用开发之 Flex 的崛起" src="http://s5.sinaimg.cn/mw690/6f56a2bfgx6C0Fea2xKa4&690" width="620" height="213" action-type="show-slide" action-data="http%3A%2F%2Fs5.sinaimg.cn%2Fmw690%2F6f56a2bfgx6C0Fea2xKa4%26690" real_src="http://s5.sinaimg.cn/mw690/6f56a2bfgx6C0Fea2xKa4&690">

在 Flex SDK Installer 里点 BROWSE 选中刚才创建的 4.10.0 目录, 如下图所示, 点 NEXT.- 跨平台移动应用开发之 Flex 的崛起" name="image_operate_68371377011868041" alt="DarkStone - 跨平台移动应用开发之 Flex 的崛起" src="http://s1.sinaimg.cn/mw690/6f56a2bfgx6C0FkzUic50&690" width="690" height="624" action-type="show-slide" action-data="http%3A%2F%2Fs1.sinaimg.cn%2Fmw690%2F6f56a2bfgx6C0FkzUic50%26690" real_src="http://s1.sinaimg.cn/mw690/6f56a2bfgx6C0FkzUic50&690">

接着选中所有的选项, 每项都有用的, 然后点 INSTALL. - 跨平台移动应用开发之 Flex 的崛起" name="image_operate_42511377011945226" alt="DarkStone - 跨平台移动应用开发之 Flex 的崛起" src="http://s13.sinaimg.cn/mw690/6f56a2bfgx6C0Fnsfak2c&690" width="690" height="624" real_src="http://s13.sinaimg.cn/mw690/6f56a2bfgx6C0Fnsfak2c&690">

等这个进度条全部走完以后, 会跳到下一个界面告诉你已完成, 届时可关闭 Flex SDK Installer.
- 跨平台移动应用开发之 Flex 的崛起" name="image_operate_90611377011965638" alt="DarkStone - 跨平台移动应用开发之 Flex 的崛起" src="http://s4.sinaimg.cn/mw690/6f56a2bfgx6C0FplxwD33&690" width="690" height="624" action-type="show-slide" action-data="http%3A%2F%2Fs4.sinaimg.cn%2Fmw690%2F6f56a2bfgx6C0FplxwD33%26690" real_src="http://s4.sinaimg.cn/mw690/6f56a2bfgx6C0FplxwD33&690">

去这里下载并安装 Flash Player 最新的 Debugger 调试版 http://www.adobe.com/support/flashplayer/downloads.html

去这里下载并安装最新的 AIR 虚拟机 http://get.adobe.com/air/

关闭所有浏览器, 安装好 Flash Player Debugger 和 AIR.

然后打开 Flash Builder 4.7, 进入菜单的 Windows -> Preferences -> Flash Builder -> Installed Flex SDKs, 点 Add... 将刚才下好的 4.10.0 的目录添加进去, SDK 的名字改为 Flex 4.10.0, 然后打上钩, 即可设为默认SDK, 如图所示:- 跨平台移动应用开发之 Flex 的崛起" name="image_operate_86211377011932710" alt="DarkStone - 跨平台移动应用开发之 Flex 的崛起" src="http://s16.sinaimg.cn/mw690/6f56a2bfgx6C0FuR8nldf&690" width="690" height="363" action-type="show-slide" action-data="http%3A%2F%2Fs16.sinaimg.cn%2Fmw690%2F6f56a2bfgx6C0FuR8nldf%26690" real_src="http://s16.sinaimg.cn/mw690/6f56a2bfgx6C0FuR8nldf&690"> 然后点 Apply 和 OK.

接下来, 对于那些 Flash Builder 里已有的 Flex 4 的项目, 对其点右键选 Properties, 检查 Flex Compiler, 看是不是用的默认的 SDK, 显示为 Flex 4.10.0, 如图所示.

- 跨平台移动应用开发之 Flex 的崛起" name="image_operate_61561377011932524" alt="DarkStone - 跨平台移动应用开发之 Flex 的崛起" src="http://s9.sinaimg.cn/mw690/6f56a2bfgx6C0FxIrXi58&690" width="690" height="506" real_src="http://s9.sinaimg.cn/mw690/6f56a2bfgx6C0FxIrXi58&690"> 如果发现是对的, 就可关掉这个窗口了.

如果你是 AIR 的项目, 进入到你的 -app.xml 配置文件.

- 跨平台移动应用开发之 Flex 的崛起" name="image_operate_16911377011845003" alt="DarkStone - 跨平台移动应用开发之 Flex 的崛起" src="http://s13.sinaimg.cn/mw690/6f56a2bfgx6C0FANPCQcc&690" width="531" height="65" real_src="http://s13.sinaimg.cn/mw690/6f56a2bfgx6C0FANPCQcc&690">

将根标签的命名空间改为 3.8

接下来, 找到 <renderMode> 标签, 反注释它, 然后设置为 <renderMode>direct</renderMode>

- 跨平台移动应用开发之 Flex 的崛起" name="image_operate_28761377010570079" alt="DarkStone - 跨平台移动应用开发之 Flex 的崛起" src="http://s12.sinaimg.cn/mw690/6f56a2bfgx6C0FFsDwffb&690" width="284" height="40" real_src="http://s12.sinaimg.cn/mw690/6f56a2bfgx6C0FFsDwffb&690">

注意, 这是最重要的地方, AIR 3.8 在 direct 渲染模式下, 大大优化了在 Mac 系统和 iOS 系统的性能, 大大提高了针对 CPU 的执行效率!
但是, AIR 3.7 和 3.6 还有以前的版本, 即便设置为 direct 也没有显著性能的提升, 只能提升 GPU 的性能, 完全没有提升 CPU 的性能.

换句话说, 到了 AIR 3.8, <renderMode>direct</renderMode> 才真正做到了对 CPU 执行效率的巨大优化.

Q&A:

Q: 在 Windows 上面没有优化?

A: 在 Windows 上, AIR 开不开 direct 渲染模式, CPU 的执行效率都很快, 没有太大的区别.

反注释 <requestedDisplayResolution> 标签, 并将其设置为 <requestedDisplayResolution>high</requestedDisplayResolution>
目前它仅对 Mac 系统的 Retina 显示屏机器(例如: Retina MacBook Pro)有效, 当你开发 Mac 系统的本地应用, 你只需要把 requestedDisplayResolution 标签设置为 high, 应用运行时 AIR 会自动将 UI 界面用 4 个物理像素显示1个逻辑像素, 意思是你的物理分辨率可能已经是 2880x1800 了, 但你的 AIR 程序的 API 告诉你, 你逻辑宽高还是 1440x900. 得到的结果就是, 在无需更改你界面任何代码和矢量素材的情况下, 完美支持视网膜屏幕!

这里我再解释下 <requestedDisplayResolution> 这个标签, 即便你的目标机器不是视网膜屏幕(也就是 dpi <= 160), 那么你将 requestedDisplayResolution 设置为 high 也不会有任何影响, 它不会在标清屏幕上放大你的 UI 界面的.

requestedDisplayResolution 对 iOS, Android 程序无效, iOS, Android 上只能通过设置 Flex Application 标签的 applicationDPI 和 runtimeDPIProvider 来缩放 UI.

那么, 新项目该怎样做呢, 新项目要做的操作跟上面的完全一样, 只不过 Flash Builder 4.7 有个 bug 会导致新建 Flex 4.10.0 项目的时候, 编译会出现问题, 我讲下:

新建的 Flex 4.10 项目, 进入主 Application 的 MXML 之后, 要将根标签的 layout="absolute" 属性删除掉, 否则不能通过编译, 这是 Flash Builder 4.7 的已知 bug 大家新建项目时一定要记住这点.

Q: 物理像素和逻辑像素的区别, AIR 程序用 4 个物理像素显示1个逻辑像素是什么意思?

A: 物理像素就是显示器实际的显像管色点, 比如 15 寸 Retina MacBook Pro 的物理分辨率是 2880x1800, 即物理水平像素数量是 2880 个, 物理垂直像素数量是 1800 个.

逻辑像素就是应用程序内部"自认为"的虚拟像素, 它的尺寸不一定等于物理像素的尺寸.

用4个物理像素呈现1个逻辑像素, 相当于 1440x900 的逻辑像素, 水平和垂直像素各自扩大2倍, 得到 2880x1800 的物理像素.

现在谈谈代码优化这一块, 如何善用 DisplayObject.cacheAsBitmap = true;

什么地方该用它, 我建议大家要注意以下几点:

1. 不要在大尺寸的显示对象上用, 何为大尺寸, 在标清屏幕上, 超过 500x500 的显示对象最好不要用, 用了可能会更卡, 因为太吃内存.

2. 不要在内部有子显示对象, 且子对象会频繁变化坐标和尺寸的显示对象上用, 用了容易崩溃, 因为虚拟机要不停为父显示对象生成不同的缓存图像, 多了容易内存溢出.

3. 所有上了滤镜 filters 的显示对象, 已经默认强行开启了缓存, 并且无法关闭这个缓存, 设不设置 DisplayObject.cacheAsBitmap = true 都无所谓.

4. 在仔细审视过前3个要点之后, 如果可以满足以下两个条件, 就推荐用:

◇ 显示对象尺寸较小, 并且可能会经常变化它本身(而不是内部子对象)的坐标.

◇ 该显示对象里有复杂的内容, 比如文字, 图片, 按钮, FXG等等.

总之, 记住以上要点, 千万不要到处写 cacheAsBitmap = true 这样的代码, 那样反而会很卡甚至崩溃.

Q: DisplayObject.cacheAsBitmap = true 是让虚拟机来生成位图缓存吧, 可否自己写程序来生成?

A: 可以, 但不推荐在 Flex 里这样做. 有人可能会觉得, 用 BitmapData.draw() 来手动生成矢量图的缓存会更好一些, 确实从性能上这个比 cacheAsBitmap 要好, 但这样做以后你的显示对象就变成了一个位图, 没有了交互性.

比如你把一个含有按钮的面板用 BitmapData.draw() 给缓存成位图了, 用户再点这个面板里的按钮就会没有反应, 因为这个面板已经栅格化为位图了; 而对于 Flex 这种需要用户随时交互的应用来说, 显然是不合适的, 所以 Flex 用 cacheAsBitmap 就够了, 它会全自动在后台为你做矢量图到位图的缓存, 并且保留矢量显示对象的可交互性.

好了, 还有最后一个要讲: applicationDPI 和 runtimeDPIProvider, 这个也是重中之重:

首先, 如果你是 Flex Desktop (桌面) 的 AIR 项目, 不要设置 applicationDPI 和 runtimeDPIProvider 这2个属性!

只需要设置 -app.xml 里的 <renderMode>direct</renderMode> <requestedDisplayResolution>high</requestedDisplayResolution> 就可以了

<renderMode>direct</renderMode>这个不管你是什么项目, 都设置为 direct 就对了, 不论是 Windows, Mac, Linux, iOS 还是 Android.

然后你的开发全部在标清显示器上做, 只要你的界面布局在标清显示器上是完美的, 那么最终部署到视网膜屏幕上也会是完美的, 是因为

<requestedDisplayResolution>high</requestedDisplayResolution>

在起作用, 4个物理像素呈现1个逻辑像素还记得吧.

现在说移动项目, 如果你是 Flex Mobile (移动) 的 AIR 项目, 那么 <requestedDisplayResolution>high</requestedDisplayResolution> 是无效的, 设置它不会帮你放大界面 UI 的尺寸.

对于 Flex Mobile 项目, 我们要设置的是 Flex Application MXML 里的 applicationDPI 和 runtimeDPIProvider 这2个属性.

首先我讲讲 Application 类 applicationDPI 和 runtimeDPI 这2个属性的关系
applicationDPI 指的是该应用程序原生是在什么 dpi 下开发和测试的.

runtimeDPI 指的是运行环境的 dpi, 注意这个值不准, 它是由 runtimeDPIProvider 折算出来的.

Flex UI 的缩放因数 = Application.runtimeDPI / Application.applicationDPI

比如说, iPhone 4 实际是 326 dpi, 经过 runtimeDPIProvider 的默认实现类折算后 Application.runtimeDPI 是 320 dpi.

那么, Application.applicationDPI 设置为 160 的话, 在 iPhone 4 上实际的 UI 缩放比例就是 320/160 = 2 也就是2倍, 这是对的.

但 iPad 3 的实际 dpi 是 264, 经过 runtimeDPIProvider 的默认实现类折算后 Application.runtimeDPI 是 240, 这就错了!

runtimeDPI = 240 的话, applicationDPI = 160 这样的话 UI 缩放就成了 1.5 倍而不是2倍, 界面布局就会错乱!

解决办法很简单, 我们写一个类, 假设其完整的包名类名是 com.test.CorrectRuntimeDPIProvider, 让它继承 mx.core.RuntimeDPIProvider 类, 并覆盖 public function get runtimeDPI():Number 方法

- 跨平台移动应用开发之 Flex 的崛起" alt="DarkStone - 跨平台移动应用开发之 Flex 的崛起" src="http://s15.sinaimg.cn/mw690/6f56a2bfgx6C0HSp766ce&690" width="376" height="75" real_src="http://s15.sinaimg.cn/mw690/6f56a2bfgx6C0HSp766ce&690">

我们根据需要自己写折算的算法, 主要从 flash.system.Capabilities 这个类提供的各项属性里获取当前设备的真实信息, 比如可获取当前设备是什么操作系统, 什么厂商, 设备名称, 真实的屏幕物理 dpi 等等, 然后自己根据需要正确实现折算的算法, 一般只要保证最终返回的 runtimeDPI 除以 applicationDPI 后等于2就对了.

官方的折算算法是很弱智的, 在 iPad 3 这种 264 物理 dpi 的设备上会返回 240 的 runtimeDPI, 正确应该返回 320 以保证 320/160 = 2.

- 跨平台移动应用开发之 Flex 的崛起" name="image_operate_19591377012575093" alt="DarkStone - 跨平台移动应用开发之 Flex 的崛起" src="http://s13.sinaimg.cn/mw690/6f56a2bfgx6C0HXfVx2bc&690" width="469" height="228" real_src="http://s13.sinaimg.cn/mw690/6f56a2bfgx6C0HXfVx2bc&690">

我们应该弃用官方 classifyDPI() 方法的实现和对它的调用, 自己正确实现 public function get runtimeDPI():Number 这个方法

实现完成后, 在主 <s:Application> 标签上面加上这样的代码就行了: applicationDPI="160" runtimeDPIProvider="com.test.CorrectRuntimeDPIProvider" frameRate="30"

做 Flex Mobile 的 AIR 项目, 一定要注意这些点:

◇ 所有的开发和设计工作, 最好全部放在标清显示器上做! 也就是代码的编写和素材的设计, 全部在标清屏幕上做.

◇ 所有的设计, 尽量做矢量素材, 导出 FXG 并优化(FXG 的优化方法在这里就不说了, 以后有空专门写个博文教大家怎样优化, 注意 FXG 代码如果不优化的话, 直接使用会很不正常), 再放入 Flash Builder 里, 在 MXML 里引用 FXG 当做标签使用.

◇ 所有的界面布局, 以在标清显示器下达到你想要的效果为准.

◇ <s:Application> 标签的 applicationDPI 永远设置为 160, 意思是当前应用是在标清屏幕上开发的.

◇ <s:Application> 标签的 runtimeDPIProvider 应该设置为一个你自己写的类, 因为官方自带的实现类太弱智, 很多情况没有考虑到位(官方以后可能会改进).

最后附上我整理的 AS3 和 Flex 官方教程和开发工具的链接:

学习使用 ActionScript 3.0 网页版: http://help.adobe.com/zh_CN/as3/learn/ PDF版: http://help.adobe.com/zh_CN/as3/learn/as3_learning.pdf (这是 AS3 语言的基本语法教程, 内容不多, 建议一口气读完)
ActionScript 3.0 开发人员指南 网页版: http://help.adobe.com/zh_CN/as3/dev/ PDF版: http://help.adobe.com/zh_CN/as3/dev/as3_devguide.pdf (这是教你 AS3 中各类 API 的使用, 内容很多, 注意不要全看! 目前只看 使用字符串 | 使用数组 | 使用 XML | 处理事件 | 显示编程 这些最常用的内容, 其它的暂时不用看)
Flex 官方视频教程 http://www.adobe.com/cn/devnet/flex/videotraining.html (视频内容是全英文的, 但很容易听懂, 不过它里面讲的很多东西, 都不是解决问题的最佳方式, 因此, 不要被这个视频里的内容先入为主了, 只拣自己感兴趣的视频看下就可以了)
Flex 开发 PC 应用教程 网页版: http://help.adobe.com/en_US/flex/using/ PDF版: http://help.adobe.com/en_US/flex/using/flex_4.6_help.pdf (这个教程只有英文版的, 并且内容非常多, 随便看看就行了)
Flex 开发移动应用教程 网页版: http://help.adobe.com/zh_CN/flex/mobileapps/ PDF版: http://help.adobe.com/zh_CN/flex/mobileapps/developing_mobile_apps_flex_4.6.pdf (这个教程目前也是随便看看即可)
AIR 开发本机扩展 网页版: http://help.adobe.com/zh_CN/air/extensions/ PDF版: http://help.adobe.com/zh_CN/air/extensions/air_extensions.pdf (利用 本机扩展, 就可让 Flex/Flash 的 AIR 应用程序调用各个平台的独立 API, 如调用 iOS 的 iCloud, GameCenter 等, 此教程有兴趣就看)
ActionScript 3.0 语言参考 http://help.adobe.com/zh_CN/FlashPlatform/reference/actionscript/3/ (这是 AS3 所有 API 的语言参考, 这个内容非常庞大, 更不用全看了, 你只用在学上面的教程时, 在这个地址查询你感兴趣的 接口 和 类的语言参考即可)

Apache Flex 语言参考 http://flex.apache.org/asdoc/ (这是 Apache Flex 最新的所有 API 语言参考, 只包含跟 Flex 有关的 API, 非常有用)
Flash Builder 开发工具下载 https://creative.adobe.com/products/flash-builder
Flash Player Debugger & PlayerGlobal 下载 http://www.adobe.com/support/flashplayer/downloads.html
AIR 虚拟机下载 http://get.adobe.com/air/
Apache Flex SDK Installer 下载 http://flex.apache.org/installer.html
如何成为 Apache Flex 开源社区的一员, 参与到 Flex 未来版本的发展中 http://flex.apache.org/community-getinvolved.html

从现在起 Flex 将重新崛起, 因为它已经是最佳的全平台应用开发解决方案!

此文章由 周戈 (DarkStone) 原创, 发表日期 2013-08-19, 转载请注明来源:

微博: http://weibo.com/dstech

博客: http://blog.sina.com.cn/dstech

QQ群: 23477140