最佳做法 - 移动设备内容创建技巧

上次更新日期: 2023年5月24日

创建用于移动设备的 Animate 内容

要为移动设备创建 Animate 内容,需要遵循一些基本原则。 例如,Animate 开发人员通常会避免使用特别复杂的图稿以及过多的补间或透明度效果。

Flash Lite开发人员面临其他挑战,因为移动设备上的性能差异很大。 如果必须将内容发布到许多不同的设备,开发人员有时必须编写最低限度的代码。

优化移动内容需要权衡取舍。 例如,一种技术可使内容看起来更出色,而另一种技术可使性能更好。 在评估这些取舍时,您需要在仿真器中的测试和目标设备上的测试之间反复来回切换。 您必须在实际设备上查看您的内容,以评估颜色的真实性、文本可读性、物理交互、UI响应性和实际移动体验的其他方面。

 Flash Lite 的有关内容不适用于 Flash CC 和更高版本。

适用于移动设备中的动画的 Flash Lite 准则

当创建用于移动设备的动画内容时,请牢记设备的 CPU 限制。 遵循这些准则有助于避免 Flash Lite 内容运行缓慢:

  • 在创建新的 Flash Lite 文件时,请检查文档是否已正确设置。 虽然 Animate 文件可以平滑缩放,但是,如果该文件没有按照其本地舞台大小运行而必须在播放器中进行缩放,则会导致性能降低。 请尝试设置文档的舞台大小以匹配目标设备的分辨率。 还应将 Flash Player 设置为 Flash Lite 的正确版本。

  • Flash Lite能以低、中和高质量渲染矢量图形。 渲染质量越高,Flash Lite渲染矢量图形的流畅度和准确性就越好,对设备CPU的需求也就越大。 为了提供复杂的动画,请尝试更改播放器的质量设置,然后彻底测试SWF文件。 若要控制SWF文件的渲染品质,请使用_quality属性或SetQuality命令。 _quality属性的有效值为LOWMEDIUMHIGH

  • 限制同时补间的数量。 减少补间数量,或对动画进行排序,使一个动画在另一个动画结束后开始。

  • 尽量少对元件使用透明度(alpha)效果,因为它们会占用大量的CPU资源。 尤其要避免将具有Alpha级别的不完全不透明(小于100%)的元件补间。

  • 避免使用占用大量 CPU 处理时间的视觉效果,如大型蒙版、剧烈运动、Alpha 混合、大量渐变和复杂的矢量图形。

  • 尝试组合使用补间、关键帧动画和 ActionScript 驱动的运动以生成运行效率最高的结果。

  • 渲染矢量椭圆和圆比渲染四边形占用更多的内存。 使用圆形和椭圆描边也会大大增加CPU使用率。

  • 经常在实际目标设备上测试动画。

  • 当 Animate 绘制动画区域时,它会在该区域周围定义一个矩形定界框。 尽量使该矩形最小以优化绘制。 Animate 会将合并区域看作一个单独的矩形,从而生成一个较大的整体区域,因此应避免重叠补间。 使用 Animate 的“显示重绘区域”功能可以优化动画。

  • 避免使用_alpha = 0_visible = false来隐藏屏幕上的影片剪辑。 如果只是关闭影片剪辑的可见性或将其Alpha更改为0,则线渲染计算中仍会包含该影片剪辑,这可能会影响性能。

  • 同样,不要尝试通过遮盖另一个图稿后面的影片剪辑来将其隐藏。 它仍然会包括在玩家的计算中。 相反,请将影片剪辑完全移出舞台,或通过调用removeMovieClip来移除它们。

移动设备中的 Flash Lite 位图和矢量图形

Flash Lite 可以对矢量图形和位图图形进行渲染。 每种类型的图形都具有其自身的优点和缺点。 有关使用矢量图形(而非位图图形)的决定并不总是显而易见的,通常取决于几个因素。

矢量图形在 SWF 文件中可用数学方程简洁地表示,并在运行时由 Flash Lite播放器渲染。 相比之下,位图图形是以图片元素(像素)的数组表示,这需要更多字节的数据。 因此,在文件中使用矢量图形可有助于减小文件大小和内存使用量。

矢量图形还可在进行大小缩放时保留其平滑形状。 位图图像可以在进行缩放时以框状(或像素化)的形式显示。

与位图相比,矢量图形需要更多的处理能力来进行渲染,特别是包含许多复杂形状和填充的矢量图形。 因此,大量使用矢量形状有时会降低文件的整体性能。 由于位图图形进行渲染所需的处理时间比矢量图形少,因此对于某些文件而言,最好是选择位图图形(例如,要在移动电话上进行动画显示和滚动的复杂道路图)。

请牢记以下注意事项:

  • 避免在矢量形状上使用轮廓。 轮廓具有内边缘和外边缘(填充只有一个边缘),是渲染工作的两倍。

  • 角比曲线更易于渲染。 如有可能,请使用平坦边缘,特别是非常小的矢量形状。

  • 对于图标等小的矢量形状,优化尤为有用。 复杂的图标可能会在渲染时丢失其细节,并且渲染细节的工作会浪费。

  • 一条通用规则是,对较小的复杂图像(如图标)使用位图;较大的简单图像使用矢量图形。

  • 按照正确的大小导入位图图形;不要导入较大的图形并在 Animate 中将它们缩小,因为这会浪费文件大小和运行时内存。

  • Flash Lite播放器不支持位图平滑处理。 如果缩放或旋转位图,它将具有厚实的外观。 如果必须缩放或旋转图形,请考虑改用矢量图形。

  • 文本本质上就是一个非常复杂的矢量形状。 当然,文本往往至关重要,因此很难完全避免。 当需要文本时,应避免为其制作动画或将文本放在动画上。 考虑将文本用作位图。 对于多行动态文本和输入文本,不会缓存文本字符串的分行符。 Animate 会在运行时换行,并在每次需要重新绘制文本字段时重新计算换行次数。 静态文本字段没有问题,因为换行是在编译时预先计算的。 对于动态内容,使用动态文本字段是不可避免的,但如有可能,请考虑改用静态文本字段。

  • 在 PNG 文件中应尽量少用透明,因为即使是位图的透明部分,Animate 也必须计算重绘。 例如,对于表示前景元素的透明 PNG 文件,不要按照屏幕的完全大小导出透明 PNG, 而是应按前景元素的实际大小将其导出。

  • 尝试将位图图层和矢量图层编成一组。 Animate 需要为位图和矢量内容采用不同的渲染器,而在渲染器之间进行切换需要花费一定的时间。

为用于移动设备的 Flash Lite 位图设置压缩

当使用位图时,可以设置用于减小 SWF 文件大小的图像压缩选项(既可以基于每个图像进行设置,也可以针对所有位图图像进行全局设置)。

设置单个位图文件的压缩选项

启动 Animate 并创建文档。

在"库"窗口中选择一个位图。
右键单击 (Windows) 或按 Control 并单击 (Macintosh)"库"窗口中的位图图标,并从上下文菜单中选择"属性"以打开"位图属性"对话框。
在"压缩"弹出菜单中,选择以下选项之一:
  • 对于具有复杂颜色或色调变化的图像(如照片或具有渐变填充的图像),请选择"照片 (JPEG)"选项。 此选项会生成一个 JPEG 文件。 选中"使用导入的 JPEG 数据"复选框可使用为导入的图像指定的默认压缩品质。 要指定新的品质压缩设置,请取消选择"使用导入的 JPEG 数据",然后在"品质"文本框中输入一个介于 1 和 100 之间的值。 设置的值越大,生成的图像品质越高,但也会生成更大的文件,因此需要相应地调整此值。

  • 对于具有简单形状和较少颜色的图像,请选择"无损 (PNG/GIF)"选项。 此选项使用无损压缩格式来压缩图像,这样不会丢弃任何数据。

单击"测试"以确定文件的压缩效果。

将原始文件大小与压缩文件大小进行比较,从而决定所选的压缩设置是否可以接受。

为所有位图图像设置压缩

选择"文件">"发布设置",然后单击"Flash"选项卡以显示压缩选项。
调整 JPEG 品质滑块或输入一个值。 JPEG 品质值越大,生成的图像的品质越高,但也会生成更大的 SWF 文件。 图像品质越低,生成的 SWF 文件就越小。 请尝试使用不同的设置,以确定文件大小和图像品质之间的最佳平衡点。

优化用于移动设备的 Flash Lite 帧

  • 大多数支持 Flash Lite 的设备以大约每秒 15 帧到 20 帧 (15-20 fps) 的速度播放内容。 帧速率可以低至6 fps。 在开发过程中,将文档帧速率设置为与目标设备的回放速度接近。 这将显示内容如何在性能有限的设备上运行。 在发布最终SWF文件之前,请将文档帧速率设置为至少20 fps或更高,以避免在设备支持较高的帧速率时限制性能。

  • 使用 gotoAndPlay 时应记住,在播放请求的帧之前,需要先对当前帧和所请求帧之间的每个帧进行初始化。 如果其中许多帧包含不同的内容,则使用不同的影片剪辑可能比使用时间轴更有效。

  • 尽管在桌面版中,通过将所有内容放在文件开头来预加载内容是合理的,但在移动设备上预加载可能会延迟文件启动。 在整个文件中为内容留出空间,以便在使用影片剪辑时进行初始化。

为移动设备上的 Flash Lite 内容优化 ActionScript

由于大多数移动设备上都存在处理速度和内存的限制,因此,开发移动设备上使用的 ActionScript for Flash Lite 内容时应遵循下列准则:

  • 尽量使文件及其代码简单。 删除未使用的影片剪辑,删除不必要的帧和代码循环,并避免出现过多的帧或无关的帧。

  • 使用FOR循环可能会很昂贵,因为每次迭代检查条件时都会产生开销。 当迭代代价和循环开销相当时,可单独执行多个操作,而不是使用循环。 代码可能更长,但性能将会改进。

  • 一旦不再需要基于帧的循环,应立即将其停止。

  • 尽量避免字符串和数组处理,因为这类处理会占用大量 CPU 处理时间。

  • 始终尝试直接访问属性,而不要使用 ActionScript getter 和 setter 方法(使用这两种方法的开销比使用其它方法调用的开销更大)。

  • 明智地管理活动。 在调用事件侦听器数组之前,使用条件检查侦听器是否存在(不是null)来保持侦听器数组紧凑。 使用unloadapplicationremoveapplicationClip删除内容之前,请通过调用clearInterval清除任何活动时间间隔,并通过调用removeListener删除任何活动侦听器。 在卸载影片剪辑时,如果有任何 ActionScript 函数仍引用 SWF 数据,则 Animate 不会回收 SWF 数据内存(例如,从间隔和侦听器回收)。

  • 当不再需要变量时,请将其删除或设置为null,这将标记它们以进行垃圾回收。 删除变量有助于优化运行时期间的内存使用,因为将从SWF文件中删除不需要的资源。 删除变量比将变量设置为null要好。

  • 在进行垃圾回收之前,可通过调用 removeListener 从对象中显式删除侦听器。

  • 如果动态调用某个函数并传递一组固定参数,则应使用 call 来代替 apply

  • 使命名空间(如路径)更紧凑以缩短启动时间。 包中的每个级别都编译为IF语句,并会导致新的对象调用,因此路径中的级别越少,节省时间。 例如,具有级别com.xxx.yyy.aaa.bbb.ccc.funtionName的路径会导致实例化com.xxx.yyy.aaa.bbb.ccc的对象。 某些Flash开发人员在编译SWF代码之前使用预处理器软件将路径减少到唯一标识符,如58923409876.functionName

  • 如果文件包含使用相同SWF类的多个ActionScript文件,请在编译期间从选择SWF文件中排除这些类。 这有助于减少文件下载时间和运行时内存要求。

  • 避免使用 Object.watchObject.unwatch,因为每次更改对象属性时,都要求播放器确定是否必须发送更改通知。

  • 如果在时间轴中的某个关键帧上执行 ActionScript 代码需要花费 1 秒多的时间才能完成,则可以考虑拆分此代码以便在多个关键帧上执行。

  • 发布SWF文件时,从代码中删除trace语句。 为此,请在“Publish设置”对话框中,选中“Flash”选项卡上的“忽略跟踪操作”复选框。

  • 继承会增加方法调用次数,并且会使用更多的内存:与从超类继承其某些功能的类相比,包含所需的所有功能的类在运行时效率更高。 因此,可能需要在类的可扩展性和代码的效率之间进行设计权衡。

  • 当一个SWF文件加载另一个包含自定义SWF类的ActionScript文件(例如,foo.bar.CustomClass),然后卸载SWF文件时,类定义保留在内存中。 要节省内存,请显式删除已卸载SWF文件中的任何自定义类。 使用delete语句并指定完全限定的类名,例如: delete foo.bar.CustomClass.

  • 限制对全局变量的使用,原因是在删除定义全局变量的影片剪辑之后,不会对这些全局变量进行标记以进行垃圾回收。

  • 避免使用标准用户界面组件(在Flash的“组件”面板中提供)。 这些组件专为在桌面计算机上运行,未针对在移动设备上运行进行优化。

  • 尽量避免将函数嵌套太深。

  • 避免引用不存在的变量、对象或函数。 与桌面版本的Flash Player相比,Flash Lite 2会缓慢查找对不存在变量的引用,这可能会对性能产生显着影响。

  • 避免使用匿名语法定义函数。 例如,myObj.eventName = function{ ...}。 显式定义的函数效率更高,如函数myFunc { ...}; my Obj.eventName = myFunc;

  • 尽可能减少Math函数和浮点数的使用。 计算这些值会降低性能。 如果必须使用Math例程,请考虑预计算这些值并将它们存储在变量数组中。 从数据表中检索值比让Flash在运行时计算它们要快得多。

管理用于移动设备的 Flash Lite 文件内存

Flash Lite 定期从内存中清除文件不再引用的所有对象和变量。 这种操作称为垃圾回收。 Flash Lite 每 60 秒运行一次垃圾回收进程,或者在文件内存使用量突然增加 20% 或更多时运行垃圾回收进程。

虽然您不能控制 Flash Lite 执行垃圾回收的方式和时间,但仍可以有意释放不需要的内存。 对于时间轴或全局变量,可以使用 delete 语句来释放 ActionScript 对象使用的内存。 对于局部变量(例如,在函数定义内定义的变量),不能使用 delete 语句来释放对象的内存,但可以将引用该对象的变量设置为 null。 在不存在对该对象进行任何其它引用的情况下,这将释放该对象使用的内存。

以下两个代码示例说明了如何通过删除引用对象的变量来释放这些对象使用的内存。 除了第一个示例创建的是时间轴变量,而第二个示例创建的是全局变量之外,这两个示例完全相同。

//第一种情况:附加到影片的变量或
//影片剪辑时间轴
//
//创建日期对象。
var mcDateObject = new Date();
//以字符串形式返回当前日期。
trace(mcDateObject);
//删除对象。
删除mcDateObject;
//返回未定义。
trace(mcDateObject);
//
//第二种情况:附加到影片的全局变量或
//影片剪辑时间轴
//
//创建日期对象。
_global.gDateObject = new Date();
//以字符串形式返回当前日期。
trace(_global.gDateObject);
//删除对象。
delete _global.gDateObject;
//返回未定义。
trace(_global.gDateObject);

正如前面提到的那样,您不能使用 delete 语句来释放本地函数变量使用的内存, 而是将变量引用设置为null,这与使用delete.
的效果相同。
函数func()

    //创建日期对象。 

    var funcDateObject = new Date(); 

    //以字符串形式返回当前日期。 

    trace(funcDateObject); 

    //删除无效。 

    delete funcDateObject; 

    //仍返回当前日期。 

    trace(funcDateObject); 

    //将对象引用设置为null。 

    funcDateObject = null; 

    //返回null。 

    trace(funcDateObject); 

//调用func()函数。 

func();func();

在 Flash Lite 中载入移动设备的数据

在开发用于移动设备的文件时,尽可能减少一次尝试加载的数据量。 如果将外部数据加载到Flash Lite文件中(例如,使用XML.load),如果为传入数据分配的内存不足,设备的操作系统可能会生成“内存故障”错误。 即使剩余内存的总量足够,也可能会出现这种情况。

例如,假设某个文件试图加载大小为 100 KB 的 XML 文件,而设备的操作系统仅分配了 30 KB 的内存来处理传入的数据流。 在这种情况下,Flash Lite 会向用户显示一个错误消息以指示内存不足。

要加载大量数据,请将数据分成较小的片段(例如,在多个XML文件中),并对每个片段进行多次数据加载调用。 每条数据的大小,以及因此而需要进行的加载数据调用的次数因设备和文件而异。 为了确定数据请求数量和内存故障可能性之间的适当平衡,请在各种目标设备上测试文件。

为获得最佳性能,请尽可能避免加载和分析XML文件。 而是以简单的名称/值对存储数据,并使用loadVars从文本文件或从预编译的SWF文件加载数据。

从 Flash Lite 的编译中排除类

要减小 SWF 文件的大小,请考虑从编译中排除类,但保留访问并使用它们进行类型检查的功能。 例如,如果您正在开发使用多个 SWF 文件或共享库的文件,特别是在这些文件或共享库访问许多相同的类时,可以尝试此方法。 排除类有助于避免重复这些文件中的类。

创建一个新的 XML 文件。
将 XML 文件命名为 FLA_filename_exclude.xml,其中 FLA_filename 是去掉 .fla 扩展名后的 FLA 文件名称。 例如,如果 FLA 文件是 sellStocks.fla,则 XML 文件名必须是 sellStocks_exclude.xml。
将文件保存在FLA文件所在的目录中。

将以下标记放在XML文件中:
<excludeAssets>
    <asset name="className1" />
    <asset name="className2" />
</excludeAssets>

<asset> 标记中的名称属性指定的值为应从 SWF 文件中排除的类的名称。 添加文件所需的数目。 例如,以下XML文件从SWF文件中排除mx.core.UIObjectmx.screens.Slide类:
<excludeAssets>
    <asset name="mx.core.UIObject" />
    <asset name="mx.screens.Slide" />
</excludeAssets>