Macromedia Flex - 3.0 User Guide

Page 1
ADOBE®FLEX
®
3
BUILDING AND DEPLOYING ADOBE FLEX 3 APPLICATIONS
Page 2
© 2008 Adobe Systems Incorporated. All rights reserved.
Building and Deploying Adobe Flex® 3 Applications
This pre-release version of the Software may not contain trademark and copyright notices that will appear in the commercially available version of the Software.
The content of this guide is furnished for informational use only, is subject to change without notice, and should not be construed as a commitment by Adobe Systems Incorporated. Adobe Systems Incorporated assumes no responsibility or liability for any errors or inaccuracies that may appe ar in the informational content contained in this guide.
Please remember that ex isting artwork or i mages that you m ay want to include i n your project m ay be protected und er copyright law. The unauthorized incorporation of such material into your new work could be a violation of the rights of the copyright owner. Please be sure to obtain any permission required from the copyright owner.
Any references to company names in sample templates are for demonstration purposes only and are not intended to refer to any actual or gani zation.
Adobe, th e Adobe logo, Flash, Flex, Flex Builder and LiveCycle are either registered trade marks or trademarks of Adobe Systems Incorp orated in the United States and/or other countries. ActiveX and Windows are either registered trademarks or trademarks of Microsoft Corporation in the United State s and/or othe r countries.
Apple and Macintosh are trademarks of Apple Inc., registered in the United States and other countries. Linux is a registered trademark of Linus Torvalds. Microsoft and Windows are either registered trademarks or trademarks of Microsoft Corporation in the United States and/or other countries. Solaris is a registered trademark or trademark of Sun Microsystems, Inc. in the United States and other countries. All other trademarks are the property of their respective owners.
This product includes software developed by the Apache Software Foundation (http://www.apache.org/).
This product contains either BISAFE and/or TIPEM software by RSA Data Security, Inc.
The Flex Builder 3 software c ontains code provided by the Eclipse Foundation (“Eclipse Cod e”). The source code for the Ecl ipse Code as contained in Flex Builder 3 software (“Eclipse Source Code”) is made available under the terms of the Eclipse Public License v1.0 which is provided herein, and is also availa ble at http://www.eclipse.org/legal/epl-v10.html .
Adobe Systems Incorporated, 345 Park Avenue, San Jose, CA 95110-2704, USA.
Notic e to U.S. gove rnme nt end users. The software and documentation are “Commercial Items,” as that term is defin ed at 48 C.F.R. §2.101, consisting of “Commercial Computer Software” and “Commercial Computer Software Documentation,” as such terms are used in 48 C.F.R. §12.212 or 48 C.F.R.
§227.7202, as applicable. Consistent with 48 C.F.R. §12.212 or 48 C.F.R. §§227.7202-1 through 227.7202-4, as applicable, the Commercial Computer Soft ware and Commercial Computer Sof tware Docu mentation are being licensed to U.S. Government en d users (a) o nly as Comm ercial items and (b) with only those rights as are granted to all other end users pursuant to the terms and conditions herein. Unpublished-rights reserved under the copyright laws of the United States. For U.S. Government End Users, Adobe agrees to comply with all applicable equal opportunity laws including, if appropriate, the provisions of Executive Order 11246, as amended, Section 402 of the Vietnam Era Veterans Readjustment Assistance Act of 1974 (38 USC 4212), and Section 503 of the Rehabilitation Act of 1973, as amended, and the regulations at 41 CFR Parts 60-1 through 60-60, 60-250 ,and 60-
741. The affirmative action clause and regulations contained in the preceding sentence shall be incorporated by reference.
Part Number: 90085059 (01/08)
Page 3
Contents
Part 1: Application Design
Chapter 1: Application Development Phases
Design phase . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
Configure phase . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
Build phase . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
Deploy phase . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
Secure phase . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
Application Development in Flex SDK . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
Chapter 2: Flex Application Structure
Installation directory structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
Development directory structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
Compiling an application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
Deployment directory structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
iii
Chapter 3: Applying Flex Security
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
Loading assets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
Using J2EE authentication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
Using RPC services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
Making other connections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
Using SSL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
Writing secure Flex applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
Configuring client security settings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
Other resources . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
Chapter 4: Optimizing Flex Applications
Improving client-side performance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
Improving charting component performance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
Chapter 5: Improving Startup Performance
About startup performance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
About startup order . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
Page 4
CONTENTS
iv
Using deferred creation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
Creating deferred components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98
Using ordered creation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
Using the callLater() method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
Chapter 6: Building Overview
About the Flex development tools . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
About application files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
Part 2: Application Development
Chapter 7: Flex SDK Configuration
About configuration files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .119
Flex SDK configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .121
Flash Player configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .123
Chapter 8: Using the Flex Compilers
About the Flex compilers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125
About the command-line compilers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131
About configuration files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .134
About option precedence . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138
Using mxmlc, the application compiler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139
Using compc, the component compiler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .161
Viewing errors and warnings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172
About SWC files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174
About manifest files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175
Using fcsh, the Flex compiler shell . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 176
Chapter 9: Using Flex Ant Tasks
Installation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .181
Using Flex Ant tasks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182
Working with compiler options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184
Using the mxmlc task . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .187
Using the compc task . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189
Using the html-wrapper task . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 190
Chapter 10: Using Runtime Shared Libraries
Introduction to RSLs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 195
Page 5
Creating libraries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .200
Using standard and cross-domain RSLs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202
Using the framework RSLs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216
Troubleshooting RSLs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 225
Chapter 11: Logging
About logging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 227
Using the debugger version of Flash Player . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 228
Client-side logging and debugging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 232
Compiler logging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 243
Chapter 12: Using the Command-Line Debugger
About debugging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 245
Starting a debugging session . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 248
Configuring the command-line debugger . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 250
Using the command-line debugger commands . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 251
Chapter 13: Using ASDoc
About the ASDoc tool . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263
Creating ASDoc comments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .264
Documenting ActionScript elements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 269
Documenting MXML files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 274
ASDoc tags . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 275
Running the ASDoc tool . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .280
v
Chapter 14: Versioning
Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .285
Using multiple SDKs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 286
Backward compatibility . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .286
Targeting Flash Player versions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .295
Part 3: Application Deployment
Chapter 15: Deploying Flex Applications
About deploying an application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 299
Deployment options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .300
Compiling for deployment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 302
Deployment checklist . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 304
Page 6
CONTENTS
vi
Chapter 16: Creating a Wrapper
About the wrapper . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .311
Creating a simple wrapper . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .315
Adding features to the wrapper . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 319
About the object and embed tags . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 321
Requesting an MXML file without the wrapper . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .332
Chapter 17: Using Express Install
About Express Install . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 333
Editing your wrapper for Express Install . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 334
Alternatives to Express Install . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 338
Chapter 18: Using the Flex Module for Apache and IIS
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .341
Getting started . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 342
Configuring the web-tier compiler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 345
Customizing the template . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 348
Debugging with the web-tier compiler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 350
Page 7
Part 1: Application Design
Top ic s
Application Development Phases. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
Flex Application Structure. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
Applying Flex Security . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
Optimizing Flex Applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
Improving Startup Performance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
1
Page 8
2
PART 1
Page 9

Chapter 1: Application Development Phases

It is difficult to define the exact process that all Adobe® Flex™ developers use to build and deploy applications. However, the process typically involves five distinct phases: design, configure, build, deploy, and secure.
Top ic s
Design phase . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
Configure phase . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
Build phase . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
Deploy phase . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
Secure phase . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
Application Development in Flex SDK . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

Design phase

3
In the design phase, you make basic decisions about how to write code for reusability, how your application interacts with its environment, how your application accesses application resources, and many other decisions. In the design phase, also define your development and deployment environments, including the directory structure of your application.
Although these design decisions specify how your application interacts with its environment, you also have archi­tectural issues to decide. For example, you might choose to develop your application based on a particular design pattern, such as Model-View-Controller (MVC).
About design patterns
One common starting point of the design phase is to identify one or more design patterns relevant for your appli­cation. A design pattern describes a solution to a common programming problem or scenario. Although the design pattern might give you insight into how to approach an application design, it does not necessarily define how to write code for that solution.
Page 10
CHAPTER 1
4
Many types of design patterns have been catalogued and documented. For example, the Functional design pattern specifies that each module of your application performs a single action, with little or no side effects for the other modules in your application. The design pattern does not specify what a module is, commonly though it corre­sponds to a class or method.
About MVC
The goal of the Model-View-Controller (MVC) architecture is that by creating components with a well-defined and limited scope in your application, you increase the reusability of the components and improve the maintain­ability of the overall system. Using the MVC architecture, you can partition your system into three categories of components:
Model components Encapsulates data and behaviors related to the data processed by the application. The model
might represent an address, the contents of a shopping cart, or the description of a product.
View components Defines your application’s user interface, and the user’s view of application data. The view
might contain a form for entering an address, a DataGrid control for showing the contents of a shopping cart, or an image of a product.
Controller components Handles data interconnectivity in your application. The Controller provides application
management and the business logic of the application. The Controller does not necessarily have any knowledge of the View or the Model.
For example, with the MVC design, you could implement a data-entry form that has three distinct pieces:
The model consists of XML data files or the remote data service calls to hold the form data.
The view is the presentation of any data and display of all user interface elements.
The controller contains logic that manipulates the model and sends the model to the view.
The promise of the MVC architecture is that by creating components with a well-defined and limited scope, you increase the reusability of these components and improve the maintainability of the overall system. In addition, you can modify components without affecting the entire system.
Although you can consider a Flex application as part of the View in a distributed MVC architecture, you can use Flex to implement the entire MVC architecture on the client. A Flex application has its own view components that define the user interface, model components that represent data, and controller components that communicate with back-end systems.
About Struts
Struts is an open-source framework that facilitates the development of web applications based on Java servlets and other related technologies. Because it provides a solution to many of the common problems that developers face when building these applications, Struts has been widely adopted in a large variety of development efforts, from small projects to large-scale enterprise applications.
Page 11
Building an d Deploying Adobe Flex 3 Applications
Struts is based on a Model-View-Controller (MVC) architecture, with a focus on the controller part of the MVC architecture. In addition, it provides JSP tag libraries to help you create the view in a traditional JSP/HTML environment.

Configure phase

Before you write your first line of application code, or before you deploy an application, you must ensure that you configure your environment correctly. Configuration is a broad term and encompasses several different tasks.
For example, you must configure your development and deployment environments to ensure that your appli­cation can access the required resources and data services. If your application requires access to a web service, ensure that your application has the correct access rights to the web service. If you application runs outside a firewall, ensure that it can access resources inside the firewall.
The following sections contain an overview of configuration tasks.
About run-time configuration
Most run-time configuration has to do with configuring access to remote data services, such as web services. For example, during application development, you run your application behind a firewall, where the application has access to all necessary resources and data services. However, when you deploy the application, you must ensure that an executing application can still access the necessary resources when the application runs outside of the firewall.
One configuration issue for Flex SDK applications is the placement of a crossdomain.xml file. For security, by default Flash Player does not allow an application to access a remote data service from a domain other than the domain from which the application was served. Therefore, a server that hosts a data service must be in the same domain as the server hosting your application, or the remote server must define a crossdomain.xml file. A cross­domain.xml file is an XML file that provides a way for a server to indicate that its data and documents are available to SWF files served from specific domains, or from all domains. By default, place the crossdomain.xml at the root directory of the server that is serving the data.
Flex SDK does not include a server-side proxy for handling data service requests. Therefore, you must ensure that you configure data services for direct access by your application, or make data service requests through your own proxy server.
5ADOBE FLEX 3
Page 12
CHAPTER 1
6

Build phase

Building your application is an iterative process that includes three main tasks:
1 Compile
2 Debug
3 Te st
About compi ling
Compiling your application converts your application files and assets into a single SWF file. During compilation, you set compiler options to enable accessibility, enable debug information in the output, set library paths, and set other options. You can configure the compiler as part of configuring your project in Flex Builder, by using command-line arguments to the compiler, or by setting options in a configuration file.
Page 13
Building an d Deploying Adobe Flex 3 Applications
When you compile your application, the Flex compiler creates a single SWF file from all of the application files (Adobe® MXML™, AS, RSL, SWC, and asset files), as the following example shows:
main.mxml
<mx:Application>
Custom
components
Compiler/Linker
ActionScript
Classes
Web Server
Client
7ADOBE FLEX 3
<..>
*.MXML
*.AS
Use <mx;Script>
*.AS
*.SWF
RSL les
*.AS
to write, import, or include ActionScript
*.AS
<..>
*.MXML
*.AS
SWC and RSL les
Flex provides two compilers: mxmlc and compc. You can use the compc and mxmlc compilers from within Flex Builder or from a command line.
You use mxmlc to compile MXML, ActionScript, SWC, and RSL files into a single SWF file. After your application is compiled and deployed on your web or application server, a user can make an HTTP request to download and play the SWF file on their computer.
You use compc to create resources that you use to create the application. For example, you can compile compo­nents, classes, and other files into SWC files or into RSLs, and then statically or dynamically link these libraries to your application.
For more information, see “Using the Flex Compilers” on page 125.
Page 14
CHAPTER 1
8
About debugging an application
Flex provides several tools that you use to debug your application, including the following:
AIR Debug Launcher (ADL) A command line version of the Adobe® AIR™ debugger that you can use outside of
Adobe® Flex™ Builder™.
Flash Player You can run Flex applications in two different versions of Adobe® Flash® Player: the standard version,
which the general public uses, and the debugger version, which application developers use to debug their appli­cations during the development process.
Flex Builder visual debugger The Flex Builder debugger allows you to run and debug applications. You can use
the debugger to set and manage breakpoints; control application execution by suspending, resuming, and termi­nating the application; step into and over the code; watch variables; evaluate expressions; and so on.
Flex Command-line debugger A command line version of the debugger that you can use outside of Flex Builder.
For more information, see “Using the Command-Line Debugger” on page 245.
About testing an application
Due to the size, complexity, and large amounts of data handled by applications, maintaining the quality of a large software application can be difficult. To help with this task, you can use automated testing tools that test and validate application behavior without human intervention.
The Flex Automation Package provides developers with the ability to create Flex applications that use the Automation API. You can use this API to create automation agents or to ensure that your applications are ready for testing. In addition, the Flex Automation Package includes support for Mercury QuickTest Professional (QTP) automation tool. for more information, see “Creating Applications for Testing” on page 356.

Deploy phase

When you deploy your application, you make it available to customers. Typically, you deploy the application as a SWF file on a web server so that users can access it by using an HTTP request to the SWF file.
When you deploy the application’s SWF file, you must also deploy all of the assets required by the application. For example, if the application requires access to video or image files, or to XML data files, you must make sure to deploy those assets as well. If the application uses an RSL, you must also deploy the RSL.
Deploying assets may not necessarily be as simple as copying the assets to a location on your web server. Flash Player has built-in security features that controls the access of application assets at run time.
This section contains an overview of the deployment phase. For more information, see “Deploying Flex Applica-
tions” on page 299.
Page 15
Building an d Deploying Adobe Flex 3 Applications
What happens during a request to a SWF file
When a customer requests the SWF file, the web server or application server returns the SWF file to the client computer. The SWF file then runs locally on the client.
In some cases, a request to a Flex SWF file can cause multiple requests to multiple SWF files. For example, if your application uses Runtime Shared Libraries (RSLs), the web server or application server returns an RSL as a SWC file to the client along with the application SWF file.
Server-side caching
Your web server or application server typically caches the SWF file on the first request, and then serves the cached file on subsequent requests. You configure server-side caching by using the options available in your web server or application server.
Client-side caching
The SWF file returned to the client is typically cached by the customer’s browser on first request. Depending on the browser configuration, the SWF file typically remains in the cache until the browser closes. When the browser reopens, the next request to the SWF file must reload it from the server.
Integrating Flex applications with your web application
To incorporate a Flex application into a website, you typically embed the SWF file in an HTML, JSP, Adobe® ColdFusion®, or other type of web page. The page that embeds the SWF file is known as the wrapper.
A wrapper consists of an <object> tag and an <embed> tag that format the SWF file on the page, define data object locations, and pass run-time variables to the SWF file. In addition, the wrapper can include support for deep linking and Flash Player version detection and deployment.
When you compile an application with Flex Builder, it automatically creates a wrapper file for you in the bin directory associated with the Flex Builder project. You can copy the contents of the wrapper file into your HTML pages to reference the SWF file.
You can edit the wrapper to manipulate how Flex appears in the browser. You can also add JavaScript or other logic in the page to communicate with Flex or generate customized pages.
When using the mxmlc command-line compiler, you must write the wrapper yourself. For more information, see
“Creating a Wrapper” on page 311.
9ADOBE FLEX 3
Page 16
CHAPTER 1
10

Secure phase

Security is not necessarily a phase of the application development process, but is an issue that you should take into consideration during the entire development process. That is, you do not configure, build, test, and deploy an application, and then define the security issues. Rather, you take security into consideration during all phases.
Building security into your application often takes the following main efforts:
Using the security features built into Flash Player
Building security into your application
Flash Player has several security features built into it, including sandbox security, that you can take advantage of because you are building applications for Flash Player.
But, Flash Player security is not enough for many application requirements. For example, your application may require the user to log in, or perform authentication in some other way, before accessing data services. When you must handle security issues beyond those built into Flash Player, design them into your application from the initial design phase, test them during the compile phase, and verify them during the deploy phase.
For more information on security, see “Applying Flex Security” on page 29.
About the security model
The Flex security model protects both the client and the server. Consider the following general aspects of security when you deploy Flex applications:
Flash Player operating in a sandbox on the client
Authorizing and authenticating users who access a server’s resources
Flash Player runs inside a security sandbox that prevents the client from being hijacked by malicious application code. This sandbox prevents a user from running a Flex application that can access system files and perform other tasks.
Flash Player security
Flash Player has an extensive list of features that ensure Flash content is secure, including the following:
Uses the encryption capabilities of SSL in the browser to encrypt all communications between a Flash appli-
cation and the server
Includes an extensive sandbox security system that limits transfer of information that might pose a risk to
security or privacy
Does not allow applications to read data from the local drive, except for SharedObjects that were created by
that domain
Does not allow writing any data to the disk except for data that is encapsulated in SharedObjects
Page 17
Building an d Deploying Adobe Flex 3 Applications
webserver.example.com
Proxy server
Application server
appserver.example.com
Web services server
nance.example.com
Web server
HTTP/SOAP
Flex application running on client machine
Does not allow web content to read any data from a server that is not from the same domain, unless that server
explicitly allows access
Enables the user to disable the storage of information for any domain
Does not allow data to be sent from a camera or microphone unless the user gives permission

Application Development in Flex SDK

The following example shows a typical development environment for a Flex SDK application:
11ADOBE FLEX 3
In this example, application development happens in an environment that is behind a firewall, and you deploy your application SWF file on webserver.example.com. To run the application, you make a request to it from a computer that is also within the firewall. The executing SWF file can access resources on any other server as necessary. In the development environment, the SWF file can directly access web services, or it can access them through a proxy server.
Page 18
CHAPTER 1
12
The following example shows a typical deployment environment for a Flex SDK application:
Flex applications on
client machine
HTTP/SOAP
Firewall/Router/DNS server
Web server
webserver.example.com
Proxy server
Application server
appserver.example.com
Web services server
nance.example.com
In this example, the customer requests the application SWF file from webserver.example.com, the server returns the SWF file to the customer, and the SWF file plays. The executing SWF file must be able to access the necessary resources from outside the firewall.
Design phase
With Flex SDK, one of your first design decisions might be to choose a design pattern that fits your application requirements. That design pattern might have implications on how you structure your development environment, determine the external data services that your application must access, and define how you integrate your Flex application into a larger web application.
Configure phase
For run-time configuration, you ensure that your executing SWF file can access the necessary resources including asset files (such as image files) and external data services. If you access a resource on a domain other than the domain from which the SWF file is served, you must define a crossdomain.xml file on the target server, or make the request through a proxy server.
Page 19
Building an d Deploying Adobe Flex 3 Applications
Build phase
To build an application for Flex SDK, you define a directory structure on your development system for application files, and define the location of application assets. You then compile, debug, and test your application.
The compile-time configuration for a Flex SDK application is primarily a process of setting compiler options to define the location of SWC and RSLs, to create a SWF file with debug information, or to set additional compiler options. When compiling applications, you compile your application into a single SWF file, and then deploy the SWF file to a web server or application server for testing.
Deploy phase
With Flex SDK, you deploy your application SWF file on your web ser ver or application server. Users then access the deployed SWF file by making an HTTP request in the form:
http://hostname/path/filename.swf
If you embed your SWF file in an HTML or other type of web page using a wrapper, users request the wrapper page. The request to the wrapper page causes the web server or application server to return the SWF file along with the wrapper page.
Secure phase
Security issues for Flex SDK applications often have to do with how the application accesses external resources. For example, you might require a user to log in to access resources, or you might want the application to be able to access external data services that implement some other form of access control.
13ADOBE FLEX 3
Page 20
14
CHAPTER 1
Page 21

Chapter 2: Flex Application Structure

One of your first tasks when developing an Adobe® Flex™ application is to set up your development directory structure. As part of setting up this directory structure, you must decide how to organize your application assets, how to share assets across applications, and how to configure the compiler to create your application SWF file.
Top ic s
Installation directory structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
Development directory structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
Compiling an application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
Deployment directory structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .26

Installation directory structure

Before you can begin to set up your application development environment, be familiar with the Flex installation directory structure for the following products:
Flex SDK
Adobe ® Flex® Builder™
15

Flex SDK installation directory structure

When you install Flex SDK, the installer creates the following directory structure under the installation directory:
Direc tory Description
/ant Contains the Flex Ant tasks, which provide a convenient way to build your Flex
/asdoc Contains ASDoc, a command-line tool that you can use to create API language
/bin Contains the executable files, such as the mxmlc and compc compilers.
/frameworks Contains configuration files, such as flex-config.xml and default.css.
/frameworks/libs Contains the library SWC files. You use the files to compile your applicatio n.
/frameworks/lo cale Contains the localization resource files.
projects.
reference documentation as HTML pages from the classes in your Flex application.
Page 22
CHAPTER 2
16
Directory Description
/frameworks/projects Contains the Flex framework source code.
/frameworks/rsls Contains the RSL for the Flex framework.
/frameworks/themes Contains the theme files that define the basic look and feel of all Flex components.
/lib Contains JAR files.
/runtimes Contains the standard and debugger versions of Adobe ® Flash® Player and the
/samples Contains sample applications.
/templates Contains template HTML wrapper files.
Adobe® AIR™ components.

Flex Builder installation directory structure

When you install Flex Builder, you install Flex SDK plus Flex Builder. The installer creates the following directory structure:
Directory Description
Flex Builder 3 The top-level directory for Flex Builder.
/configuration A standard Eclipse folder that contains the config.ini file and error logs.
/features A standard Eclipse folder that contains the plug-ins corresponding to features of Flex
/jre Contains the Java Runtime Environment installed with Flex Builder used by default when
/Player Contains the different versions of Flash Player—the standa rd version and the debugger
/plugins Contains the Eclipse plugins used by Flex Builder.
/sdks Contains the different Flex SDKs. For a directo ry description, see “Flex SDK installation direc-
Builder.
you run the stand-alone version of Flex Builder.
version.
tory structure” on page 15.
Page 23
Building an d Deploying Adobe Flex 3 Applications

Development directory structure

As part of the process of setting up the directory structure of your development environment, you define the directory location for application-specific assets, assets shared across applications, and the location of other appli­cation files and assets.

Flex file types

A Flex application consists of many different file types. Consider the following options when you decide where to place each type of file.
The following table describes the different Flex file types:
Fil e for mat Extension Description
17ADOBE FLEX 3
MXML .mxml Your application typically has one main application MXML file that contains the
Action Scrip t .as A utility class, Flex custom component class, or other logic implemented as an Action-
SWC .swc A custom library file, or a custom component implemented as an MXML or ActionScri pt
RSL .swc A custom library imp lemented as an MXML or ActionScript file, and t hen deployed as a
CSS file .css A text file template for creating a Cascading Style Sheets file.
Assets .flv, .mp3, .jpg, .gif, .swf, .png,
.svg, .xml, other
<mx:Applicatio n> tag, and one or more MXML files that implement your custom
MXML components.
Script file.
file, then packaged as a SWC file.
A SWC file contains components that you package and reuse among multiple applica­tions. The SWC file is then statically linked into your application at compile time when you create the application’s SWF file.
Runtime Shared Library (RSL). An RSL is a stand-alone SWC file that is downloaded separately from your application’s SWF file, cached on the client computer for use with multiple application SWF files, and dynamically linked to your application.
The assets required by your application, including image, skin, soun d, and video files.

Flex SDK directory structure

A typical Flex application consists of a main MXML file (the file that contains the <mx:Application> tag), one or more MXML files that implement custom MXML components, one or more ActionScript files that contains custom components and custom logic, and asset files.
Page 24
CHAPTER 2
18
The following example shows an example of the directory structure of a simple Flex application:
appRoot
mainApp.mxml
myValidators
PriceValidator.mxml
AddressValidator.as
myFormatters
PriceFormatter.mxml
StringFormatter.as
assets
logo.gif
splashScreen.gif
.settings (Flex Builder only)
bin (Flex Builder only)
html-template (Flex Builder only)
This application consists of a root application directory and directories for different types of files. Everything required to compile and run the application is contained in the directory structure of the application.
Flex Builder adds additional directories to the application that are not present for Flex SDK applications:
.settings Contains the preference settings for your Flex Builder project
bin-debug Contains the debug SWF and debug wrapper files
bin-release Contains the generated SWF file and wrapper file, created by Flex Builder when you select File >
Export > Release Version
html-template Contains additional files used by specific Flex features, such as deep linking or Player detection.
Flex Builder uses these files to generate an HTML wrapper for your SWF file.
Page 25
Building an d Deploying Adobe Flex 3 Applications
appRoot1
localAssets
localAssets
appRoot2
sharedAssets
myApps
There are no inherent restrictions in Flex for the location of the root directory of your application, so you can put it almost anywhere in the file system of your computer. If you are using Flex Builder, the default location of the application root directory in Microsoft Windows is My Documents\Flex Builder 3\project_name (for example, C:\Documents and Settings\userName\My Documents\Flex Builder 3\myFlexApp).
Sharing assets among applications
Typically, you do not develop a single application in isolation from all other applications. Your application shares files and assets with other applications.
The following example shows two Flex applications, appRo ot1 and appRo ot2. E ach applicati on has a directory for local assets, and can access shared assets from a directory outside of the application’s directory structure:
19ADOBE FLEX 3
The location of the shared assets does not have to be at the same level as the root directories of the Flex applica­tions. It only needs to be somewhere accessible by the applications at compile time.
In the following example, you use the Image control in an MXML file in the appRoot1 directory to access an asset from the shared assets directory:
<?xml version="1.0"?> <!-- apparch/EmbedExample.mxml --> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"> <mx:Image id="loader1" source="@Embed(source='../assets/butterfly.gif')"/> </mx:Application>
Consideration for accessing application assets
One of the decisions that you must make when you create a Flex application is whether to load your assets at run time, or to embed the assets within the application’s SWF file.
Page 26
CHAPTER 2
20
When you embed an asset, you compile it into your application’s SWF file. The advantage to embedding an asset is that it is included in the SWF file, and can be accessed faster than having to load it from a remote location at run time. The disadvantage of embedding is that your SWF file is larger than if you load the asset at run time.
If you decide to access an asset at run time, you can load it from the local file system of the computer on which the SWF file runs, or you can access a remote asset, typically though an HTTP request over a network.
A SWF file can access one type of external asset: local or over a network; the SWF file cannot access both types. You determine the type of access allowed by the SWF file by using the application. When you set the over the network. The default value is
use-network flag to false, you can access assets in the local file system, but not
true, which lets you access assets over the network, but not in the local file
use-network flag when you compile your
system.
For more information on the use-network flag, see “Using the Flex Compilers” on page 125. For more infor- mation on embedding application assets, see “Embedding Assets” on page 965 in the Adobe Flex 3 Developer Guide.
Sharing MXML and ActionScript files among applications
You can build an entire Flex application in a single MXML file that contains both your MXML code and any supporting ActionScript code. As your application gets larger, your single file also grows in size and complexity. This type of application would soon become difficult to understand and debug, and very difficult for multiple developers to work on simultaneously.
Flex supports a component-based development model. You use the predefined components included with Flex to build your applications, and create components for your specific application requirements. You can create custom components using MXML or ActionScript.
Defining your own components has several benefits. One advantage is that components let you divide your appli­cations into modules that you can develop and maintain separately. By implementing commonly used logic within custom components, you can also build a suite of reusable components that you can share among multiple Flex applications.
Page 27
Building an d Deploying Adobe Flex 3 Applications
The following example shows two Flex applications, appRoot1 and appRoot2. Each application has a subdirectory for local MXML and ActionScript components, and can also reference a library of shared components:
my Apps
appRoot1
myValidators
PriceValidator.mxml
AddressValidator.as
myFormatters
PriceFormatter.mxml
StringFormatter.as
appRoot2
myValidators
21ADOBE FLEX 3
myFormatters
sharedLibrary
sharedValidators
SharedVal1.mxml
SharedVal2.as
sharedFormatters
SharedFormatter1.mxml
SharedFormatter2.as
The Flex compiler uses the source path to determine the directories where it searches for MXML and ActionScript files. By default, the root directory of the application is included in the source path; therefore, a Flex application can access any MXML and ActionScript files in its main directory, or in a subdirectory.
Page 28
CHAPTER 2
22
For shared MXML and ActionScript files that are outside of the application’s directory structure, you modify the source path to include the directories that the compiler searches for MXML and ActionScript files. The component search order in the source path is based on the order of the directories listed in the source path.
You can set the source path as part of configuring your project in Flex Builder, in the flex-config.xml file, or set it when you open the command-line compiler. In this example, you set the source path to:
C:\myApps\sharedLibrary
To access a component in an MXML file, you specify a namespace definition that defines the directory location of the component relative to the source path. In the following example, an MXML file in the appRoot1 directory accesses an MXML component in the local directory structure, and in the directory containing the shared library of components:
<?xml version="1.0"?> <!-- apparch/ComponentNamespaces.mxml --> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:MyLocalComps="myFormatters.*" xmlns:MySharedComps="sharedFormatters.*" >
<MyLocalComps:PriceFormatter/>
<MySharedComps:SharedFormatter2/>
</mx:Application>
The MXML tag name for a custom component is composed of two parts: the namespace prefix, in this example MyLocalComps and MySharedComps, and the tag name. The namespace prefix tells Flex the directory in the source path that contains the file that implements the custom component. The tag name corresponds to the filename of the component, in this example PriceFormatter.mxml and SharedFormatter2.mxml.
Using a SWC file in a Flex SDK application
A SWC file is a Flex library file that contains one or more components implemented in MXML or ActionScript. All Flex library files are shipped as SWC files in the frameworks/libs directory. This includes the following SWC files:
framework.swc
playerglobal.swc
rpc.swc
Page 29
Building an d Deploying Adobe Flex 3 Applications
You can also create SWC files that you package and reuse among multiple applications. You typically use static linking with SWC files, which means the compiler includes all components, classes, and their dependencies in the application SWF file when you compile the application. For more information on static linking, see “A b o u t
linking” on page 196.
By default, the Flex compiler includes all SWC files in the frameworks/libs directory when it compiles your appli­cation. For your custom SWC files, you use the
library-path option of the mxmlc compiler, or set the library
path in Flex Builder, to specify the location of the SWC file.
Using an RSL in a Flex SDK application
One way to reduce the size of your application’s SWF file is by externalizing shared assets into stand-alone files that can be separately downloaded and cached on the client. These shared assets are loaded by any number of applications at run time, but must be transferred to the client only once. These shared files are known as Runtime Shared Libraries or RSLs.
An RSL is a stand-alone file that the client downloads separately from your application’s SWF file, and caches on the client computer for use with multiple application SWF files. Using an RSL reduces the resulting file size for your applications. The benefits increase as the number of applications that use the RSL increases. If you only have one application, putting components into RSLs does not reduce the aggregate download size, and might increase it.
You create an RSL as a SWC file that you package and reuse among multiple applications. To reference an RSL, you use the
runtime-shared-libraries option for the command-line compiler, or Flex Builder. You typically
use dynamic linking with RSLs, which means that the classes in the RSL are left in an external file that is loaded at run time.
Every Flex application uses some aspects of the Flex framework, which is a relatively large set of ActionScript classes that define the infrastructure of a Flex application. If a client loads two different Flex applications, the application will likely load overlapping class definitions. To further reduce the SWF file size, you can use framework RSLs. Framework RSLs let you externalize the framework libraries and can be used with any Flex appli­cation.
For more information on RSLs, framework RSLs, and dynamic linking, see “Using Runtime Shared Libraries” on
page 195.
23ADOBE FLEX 3
Using modules in a Flex SDK application
Modules are SWF files that can be loaded and unloaded by an application. They cannot be run independently of an application, but any number of applications can share the modules.
Page 30
CHAPTER 2
24
Modules let you split your application into several separate SWF files. The main application, or shell, can dynam­ically load other SWF files that it requires, when it needs them. It does not have to load all modules when it starts, nor does it have to load any modules if the user does not interact with them. When the application no longer needs a module, it can unload the module to free up memory and resources.
For more information, see “Creating Modular Applications” on page 981.

Compiling an application

Compiling your application converts your application files and assets into a single SWF file. During compilation, you set compiler options to enable accessibility, enable debug information in the output, set library paths, and set other options. You can configure the compiler as part of configuring your project in Flex Builder, by using command-line arguments to the compiler, or by setting options in a configuration file.
For more information on compiling applications, see “Using the Flex Compilers” on page 125.

About case sensitivity during a compile

The Flex compilers use a case-sensitive file lookup on all file systems. On case-insensitive file systems, such as the Macintosh and Windows file systems, the Flex compiler generates a case-mismatch error when you use a component with the incorrect case. On case-sensitive file systems, such as the UNIX file system, the Flex compiler generates a component-not-found error when you use a component with the incorrect case.

Compiling a Flex SDK application

Flex SDK includes two compilers, mxmlc and compc. You use mxmlc to compile MXML files, ActionScript files, SWC files, and RSLs into a single SWF file. After your application is compiled and deployed on your web or appli­cation server, a user can make an HTTP request to download and play the SWF file on their computer. You use the compc compiler to compile components, classes, and other files into SWC files or RSLs.
To compile an application with Flex SDK, you use the mxmlc compiler in the bin directory of your Flex SDK directory. The most basic mxmlc example is one in which the MXML file for your application has no external dependencies (such as components in a SWC file or ActionScript classes). In this case, you open mxmlc from the command line and point it to your MXML file, as the following example shows:
$ mxmlc c:/myFiles/app.mxml
Page 31
Building an d Deploying Adobe Flex 3 Applications
The mxmlc compiler has many options that you can specify on the command line, or that you can set in the flex­config.xml file. For example, to disable warning messages, you set the
warnings options to false, as the following
example shows:
$ mxmlc -warnings=false c:/myFiles/app.mxml
You only specify the main application file, the file that contains the <mx:Application> tag, to the compiler. The compiler searches the default source path for any MXML and ActionScript files that your application references. If your application references MXML and ActionScript files in directories that are not included in the default source path, you can use the
source-path option to add a directory to the source path, as the following example
shows:
$ mxmlc -source-path path1 path2 path3 c:/myFiles/app.mxml
In this example, you specify a list of directories, separated by spaces, and terminate that list with --.
Compiling an application that uses SWC files
Often, you use SWC files when compiling MXML files. You specify the SWC files in the compiler by using the
library-path option.
The following example adds two SWC files to the
$ mxmlc -library-path+=/myLibraries/MyRotateEffect.swc;/myLibraries/MyButtonSwc.swc c:/myFiles/app.mxml
library-path when it compiles your application:
25ADOBE FLEX 3
Compiling an application that uses RSLs
To use an RSL in your application, use the runtime-shared-library-path compiler option. The following example compiles an application with an RSL at the command line:
$ mxmlc -runtime-shared-library-path=../lib/mylib.swc,../bin/library.swf Main.mxml
Compiling an application that uses modules
The way you compile modules is similar to the way you compile Flex applications. On the command line, you use the mxmlc command-line compiler. The result is a SWF file that you load into your application as a module.
You cannot run the module-based SWF file as a stand-alone application or load it into a browser window. It must be programmatically loaded by an application as a module.
For more information on compiling modules on the command line, see “Creating Modular Applications” on
page 981
Page 32
CHAPTER 2
26

Compiling a Flex Builder application

When you compile a project with Flex Builder, you open the Flex compilers from within Flex Builder itself, not from the command line. You can build your projects manually or let Flex Builder automatically compile them for you. In either case, the Flex Builder compiler creates the SWF application files, generates a wrapper, places the output files in the proper location, and alerts you to any errors encountered during compilation. You then run and debug your applications as needed.
If you must modify the default build settings, you have several options for controlling how your projects are built into applications. For example, you can set build preferences on individual projects or on all the projects in your workspace, modify the build output path, change the build order, and so on. You can also create custom build instructions using third-party tools, such as Apache Ant.
When your projects are built, automatically or manually, Flex Builder places the SWF file in the project output folder along with the wrapper. By default, this is the debug version of your application. It contains debugging information and, therefore, is used when you debug your application. A wrapper file embeds the application SWF file and is used to run or debug your application in a web browser. The standard version of your application SWF files, which you generate through Export Release Version, does not include the additional debugging information and is smaller.
Compiling an application that uses modules
In Flex Builder, you create modules as applications and compile them by either building the project or running the application. The result is a SWF file that you load into your application as a module.
You cannot run the module-based SWF file as a stand-alone Flex application or load it into a browser window. It must be loaded by an application as a module. When you run it in Flex Builder to compile it, you should close the Player or browser Window and ignore any errors. Modules should not be requested by the Player or through a browser directly.
For information on compiling modules in Flex Builder, see “Creating Modular Applications” on page 981

Deployment directory structure

When you deploy an application, ensure that the directory structure of the deployed application is correct.
When you deploy your application, must be aware of how your application accesses its assets. If you embedded all of your application assets into the SWF file, you can deploy the application as a stand-alone SWF file.
Page 33
Building an d Deploying Adobe Flex 3 Applications
However, if your application accesses assets at run time, the application requests assets during execution. You must ensure that you deploy all of the necessary assets, in the correct location, so that you can run the application correctly.
Assets that you deploy at run time include:
HTML wrapper
Deep linking files
Express Install files
RSLs
Modules
Compiled CSS SWF files
Resource modules (for localization)
Images, sound files, and other binary assets that are not embedded
Data files
In some cases, the deployed locations of these files must match the locations of the files during development. For example, if you load modules from the same directory as your main application, then you must deploy these modules to that directory, unless you programmatically handle alternative locations to load the modules from.
In other cases, the deployed locations of these files is specified. For example, the deep linking files history.css, historyFrame.html, and history.js must all reside in a /history subdirectory that is located relative to the appli­cation’s SWF file.
And in other cases, you specify the eventual deployed location of these assets when you compile your application. For example, if you compiled your application using an RSL, you must ensure that the RSL is also deployed to your web server, along with your application’s SWF file. The directory location of the RSL must match the directory location that you specified at compile time using the
library-path
options for the compiler.
runtime-shared-libraries or runtime-shared-
For more information about what assets to deploy with your application, see “Deployment checklist” on page 304.
27ADOBE FLEX 3
Page 34
CHAPTER 2
28
Page 35

Chapter 3: Applying Flex Security

Developers (including programmers and other authors) who design and publish Flex applications can control the security aspects of the applications they develop by using Flex.
Top ic s
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .29
Loading assets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
Using J2EE authentication. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
Using RPC services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
Making other connections. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
Making other connections. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
Using SSL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
Writing secure Flex applications. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
Configuring client security settings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .53
Other resources . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
29

Introduction

Adobe® Flash® Player runs applications built with Flash. (These applications are also referred to as SWF files). Content is delivered as a series of instructions in binary format to Flash Player over web protocols in the precisely described SWF (.swf) file format. The SWF files themselves are typically hosted on a server and then downloaded to, and displayed on, the client computer when requested. Most of the content consists of binary ActionScript instructions. ActionScript is the ECMA standards-based scripting language that Flash uses that features APIs designed to allow the creation and manipulation of client-side user interface elements and for working with data.
The Flex security model protects both client and the server. Consider the following two general aspects to security:
Authorization and authentication of users accessing a server’s resources
Flash Player operating in a sandbox on the client
Page 36
CHAPTER 3
30
Flex supports working with the web application security of any J2EE application server. In addition, precompiled Flex applications can integrate with the authentication and authorization scheme of any underlying server technology to prevent users from accessing your applications. The Flex framework also includes several built-in security mechanisms that let you control access to web services, HTTP services, and server-based resources such as EJBs.
Flash Player runs inside a security sandbox that prevents the client from being hijacked by malicious application code.
Note: SWF content running in the Adobe® AIR™ follows different security rules than content running in the browser. For details, see the "AIR Security" section in Developing AIR Applications with Adobe Flex 3.

Declarative compared to programmatic security

The two common approaches to security are declarative and programmatic. Often, declarative security is server based. Using the server’s configuration, you provide protection to a resource or set of resources. You use the container’s authentication and authorization schemes to protect that resource from unauthorized access.
The declarative approach to security casts a wide net. Declarative security is implemented as a separate layer from the web components that it works with. You set up a security system, such as a set of file permissions or users, groups, and roles, and then you plug your application's authentication mechanism into that layer.
With declarative security, either a user gains access to the resource or they do not. Usually the content cannot be customized based on roles. In an HTML-based application, the result is that users are denied access to certain pages. However, in a Flex environment, the typical result of declarative security is that the user is denied access to the entire application, since the application is seen as a single resource to the container.
Declarative security lets programmers who write web applications ignore the environment in which they write. Declarative security is typically set up and maintained by the deployer and not the developer of the application. Also, updates to the web application do not generally require a refactoring of the security model.
Programmatic security gives the developer of the application more control over access to the application and its resources. Programmatic security can be much more detailed than declarative security. For example, a developer using programmatic security can allow or deny a user access to a particular component inside the application.
Although programmatic security is typically configured by the developer of the application, it usually interacts with the same systems as declarative security, so the relationship between developer and deployer of the appli­cation must be cooperative when implementing programmatic security.
Page 37
Building an d Deploying Adobe Flex 3 Applications
Declarative security is recommended over programmatic security for most applications because the design promotes code reuse, making it more maintainable. Furthermore, declarative security puts the responsibility of security into the hands of the people who specialize in its implementation; application programmers can concen­trate on writing applications and people who deploy the applications in a specific environment can concentrate on enforcing security policies and take advantage of that context.

Client security overview

When considering security issues, you cannot think of Flex applications as traditional web applications. Flex applications often consist of a single monolithic SWF file that is loaded by the client once, or a series of SWF files loaded as modules or RSLs. Web applications, on the other hand, usually consist of many individual pages that are loaded one at a time.
Most web applications access resources such as web services that are outside of the client. When a Flex application accesses an external resource, two factors apply:
Is the user authorized to access this resource?
Can the client load the resource, or is it prevented from loading the resource, because of its sandbox limita-
tions?
The following basic security rules always apply by default:
Resources in the same security sandbox can always access each other.
SWF files in a remote sandbox can never access local files and data.
You should consider the following security issues related to the client architecture that affect Flex applications.
31ADOBE FLEX 3
Flash Player security features
Much of Flash Player security is based on the domain of origin for loaded SWF files, media, and other assets. A SWF file from a specific Internet domain, such as www.example.com, can always access all data from that domain. These assets are put in the same security grouping, known as a security sandbox. For example, a SWF file can load SWF files, bitmaps, audio, text files, and any other asset from its own domain. Also, cross-scripting between two SWF files from the same domain is permitted, as long as both files are written using ActionScript 3.0. Cross­scripting is the ability of one SWF file to use ActionScript to access the properties, methods, and objects in another SWF file. Cross-scripting is not supported between SWF files written using ActionScript 3.0 and files using previous versions of ActionScript; however, these files can communicate by using the LocalConnection class.
Memory usage an d disk storage protec tions
Flash Player includes security protections for disk data and memory usage on the client computer.
Page 38
CHAPTER 3
32
The only type of persistent storage is through the SharedObject class, which is embodied as a file in a directory whose name is related to that of the owning SWF file. A Flex application cannot typically write, modify, or delete any files on the client computer other than SharedObject data files, and it can only access SharedObject data files under the established settings per domain.
Flash Player helps limit potential denial-of-service attacks involving disk space (and system memory) through its monitoring of the usage of SharedObject classes. Disk space is conserved through limits automatically set by Flash Player (the default is 100K of disk space for each domain). The author can set the application to prompt the user for m ore disk sp ace, or F lash Playe r automatically pr ompts the u ser if an at tempt is made to store data that ex ceeds the limit. In either case, the disk space limit is enforced by Flash Player until the user gives explicit permission for an increased allotment for that domain.
Flash Player contains memory and processor safeguards that help prevent applications from taking control of excess system resources for an indefinite period of time. For example, Flash Player can detect an application that is in an infinite loop and select it for termination by prompting the user. The resources that the application uses are immediately released when the application closes.
Flash Player uses a garbage collector engine. The processing of new allocation requests always first ensures that memory is cleared so that the new usage always obtains only clean memory and cannot view any previous data.
Privacy
Privacy is an important aspect of overall security. Adobe products, including Flash Player, provide very little infor­mation that would reveal anything about a user (or their computer). Flash Player does not provide personal infor­mation about users (such as names, e-mail addresses, and phone numbers), or provide access to other sensitive information (such as credit card numbers or account information).
What Flash Player does provide is basically standardized hardware and software configuration information that authors might use to enhance the user experiences in the environment encountered. The same information is often available already from the operating system or web browser.
Information about the client environment that is available to the Flex application includes:
User agent string, which typically identifies the embedding browser type and operating system of the client
System capabilities such as the language or the presence of an MP3 decoder (see the Capabilities class)
Presence of a camera and microphone
Keyboard and mouse input
ActionScript also includes the ability to replace the contents of the client’s Clipboard by using the
setClipboard() method of the System class. This method does not have a corresponding getClipboard()
method, so protected data that might be stored in the Clipboard already is not accessible to Flash Player.
Page 39
Building an d Deploying Adobe Flex 3 Applications
About sandboxes
The sandbox type indicates the type of security zone in which the SWF file is operating. In Flash Player, all SWF files (and HTML files, for the purposes of SWF-to-HTML scripting) are placed into one of four types of sandbox:
remote All files from non-local URLs are placed in a remote sandbox. There are many such sandboxes, one for
each Internet (or intranet) domain from which files are loaded.
local-with-filesystem The default sandbox for local files. SWF files in this sandbox may not contact the Internet
(or any servers) in any way—they may not access network endpoints with addresses such as HTTP URLs.
local-with-networking SWF file in this sandbox may communicate over the network but may not read from local
file systems.
local-trusted This sandbox is not restricted. Any local file can be placed in this sandbox if given authorization by
the end user. This authorization can come in two forms: interactively through the Settings Manager or noninter­actively through an executable installer that creates Flash Player configuration files on the user’s computer.
You can determine the current sandbox type by using the
sandboxType property of the Security class, as the
following example shows:
<?xml version="1.0" encoding="utf-8"?> <!-- security/DetectCurrentSandbox.mxml --> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="initApp()"> <mx:Script><![CDATA[ [Bindable] private var l_sandboxType:String;
33ADOBE FLEX 3
private function initApp():void { l_sandboxType = String(Security.sandboxType); } ]]></mx:Script>
<mx:Form> <mx:FormItem id="fi1" label="Security.sandboxType"> <mx:Label id="l1" text="{l_sandboxType}"/> </mx:FormItem> </mx:Form>
</mx:Application>
When you compile a Flex application, you have some control over which sandbox the application is in. This deter­mination is a combination of the value of the
use-network compiler option (the default is true) and whether the
SWF file was loaded by the client over a network connection or as a local file.
Page 40
CHAPTER 3
34
The following table shows how the sandbox type is determined:
use-network Loaded Sandbox type
false locally local-with-filesystem
true locally local-with-network
true network remote
false network n/a (causes an error)
Browser security
Flash Player clients can be one of the following four types:
Embedded Flash Player
Debugger version of embedded Flash Player
Stand-alone Flash Player
Debugger version of stand-alone Flash Player
The stand-alone Flash Player runs on the desktop. It is typically used by people who are running applications that are installed and maintained by an IT department that has access to the desktop on which the application runs.
The embedded Flash Player is run within a browser. Anyone with Internet access can run applications from anywhere with this player. For Internet Explorer, the embedded player is loaded as an ActiveX control inside the browser. For Netscape-based browsers (including Firefox), it is loaded as a plug-in inside the browser. Using an embedded player lets the developer use browser-based technologies such as FORM and BASIC authentication as well as SSL.
Browser APIs
Applications hosting the Flash Player ActiveX control or Flash Player plug-in can use the EnforceLocalSecurity and DisableLocalSecurity API calls to control security settings. If DisableLocalSecurity is opened, the application does not benefit from the local-with-networking and local-with-file-system sandboxes. All files loaded from the local file system are placed into the local-trusted sandbox. The default behavior for an ActiveX control hosted in a client application is DisableLocalSecurity.
If EnforceLocalSecurity is opened, the application can use all three local sandboxes. The default behavior for the browser plug-in is EnforceLocalSecurity.
Cross-scripting
Cross-scripting is when a SWF file communicates directly with another SWF file. This communication includes calling methods and setting properties of the other SWF file.
Page 41
Building an d Deploying Adobe Flex 3 Applications
SWF file loading and cross-scripting are always permitted between SWF files that reside in the same sandbox. For example, any local-with-filesystem SWF file can load and cross-script any other local-with-filesystem SWF file; any local-with-networking SWF file can load and cross-script any other local-with-networking SWF file; and so on. The restrictions appear when two SWF files from different sandboxes or two remote SWF files with different domains attempt to cooperate.
For SWF files in the remote sandbox, if two SWF files were loaded from the same domain, they can cross-script without any restrictions. If both SWF files were loaded from a network, but from different domains, you must provide permissions to allow them to cross-script.
To enable cross-scripting between SWF files, use the Security class’s
allowInsecureDomain() methods.
allowDomain() and
You call these methods from the called SWF file and specify the calling SWF file’s domain. For example, if SWF1 in domainA.com calls a method in SWF2 in domainB, SWF2 must call the allowDomain() method and specifi­cally allow SWF files from domainA.com to cross-script the method, as the following example shows:
import flash.system.Security; Security.allowDomain("domainA.com");
If the SWF files are in different sandboxes (for example, if one SWF file was loaded from the local file system and the other from a network) they must adhere to the following set of rules:
Remote SWF files (those served over HTTP and other non-local protocols) can never load local SWF files.
Local-with-networking SWF files can never load local-with-filesystem SWF files, or vice versa.
Local-with-filesystem SWF files can never load remote SWF files.
Local-trusted SWF files can load SWF files from any sandbox.
To facilitate SWF-to-SWF communication, you can also use the LocalConnection class. For more information, see “Using the LocalConnection class” on page 46.
35ADOBE FLEX 3
ExternalInterface
You use the ExternalInterface API to let your Flex application call scripts in the wrapper and to allow the wrapper to call functions in your Flex application. The ExternalInterface API consists primarily of the
addCallback() methods in the flash.net package.
This communication relies on the domain-based security restrictions that the
allowNetworking properties define. You set the values of the allowScriptAccess and allowNetworking
allowScriptAccess and
call() and
properties in the SWF file’s wrapper. For more information, see “About the object and embed tags” on page 321.
By default, the Flex application and the HTML page it is calling must be in the same domain for the
call()
method to succeed. For more information, see “Communicating with the Wrapper” on page 1035 in the Adobe Flex 3 Developer Guide.
Page 42
CHAPTER 3
36
The navigateToURL() method
The navigateToURL() method opens or replaces a window in the Flash Player’s container application. You typically use it to launch a new browser window, although you can also embed script in the method’s call to perform other actions.
This usage of the
allowScriptAccess and allowNetworking parameters define. You set the values of the allowScriptAccess
and
allowNetworking parameters in the SWF file’s wrapper. For more information, see “Ab o u t t h e o b j e c t a n d
navigateToURL() method relies on the domain-based security restrictions that the
embed tags” on page 321.
Cachi ng
Flex applications reside entirely on the client. If the browser loads the application, the application SWF file, plus externally loaded images and other media files, are stored locally on the client in the browser’s cache. These files reside in the cache until cleared.
Storing a SWF file in the browser’s cache can potentially expose the file to people who would not otherwise be able to see it. The following table shows some example locations of the browser’s cache files:
Broswer or operating system Cache location
Internet Explorer on Windows XP C:\Documents and Settings\username\Local Settings\Temporary Internet Files
Firefox on Windows XP C:\Documents and Settings\username\Applicatio n Data\Mozilla\Firefox\Profiles\user-
UNIX $HOME/.mozilla/firefox/username.default/Cache/
name.default\Cache
These files can remain in the cache even after the browser is closed.
To prevent client browsers from caching the SWF file, try setting the following HTTP headers in the wrapper that returns the Flex application’s SWF file:
Cache-control: no-cache, no-store, must-revalidate, max-age=-1 Pragma: no-cache, no-store Expires: -1
Trusted sites and directories
The browser security model includes levels of trust applied to specific websites. Flash Player interacts with this model by assigning a sandbox based on whether the browser declared the site of the SWF file’s origin trusted.
If Flash Player loads a SWF file from a trusted website, the SWF file is put in the local-trusted sandbox. The SWF file can read from local data sources and communicate with the Internet.
Page 43
Building an d Deploying Adobe Flex 3 Applications
You can also assign a SWF file to be in the local-trusted sandbox when you load it from the local file system. To do this, you configure a directory as trusted by Flash Player (which results in the SWF file being put in the local­trusted sandbox) by adding a FlashPlayerTrust configuration file that specifies the directory to trust. This requires administrator access privileges to the client system, so it is typically used in controlled environments. Users can also define a directory as trusted by using the Flash Player User Settings Manager. For more information, see Flash Player documentation.

Deploying secure applications

When you deploy an application, you make the application accessible to your users. The process of deploying an application is dependent on your application, your application requirements, and your deployment environment. You can employ some of the following strategies to ensure that the application you deploy is secure.
Deploying local SWF files versus network SWF files
Client computers can obtain individual SWF files from a number of sources, such as from an external website or a local file system. When SWF files are loaded into Flash Player, they are individually assigned to security sandboxes based on their origin.
Flash Player classifies SWF files downloaded from the network (such as from external websites) in separate sandboxes that correspond to their website origin domains. By default, these files are authorized to access additional network resources that come from the specific (exact domain name match) site. Network SWF files can be allowed to access additional data from other domains by explicit website and author permissions.
A local SWF file describes any file referenced by using the “file:\\” protocol or a UNC path, which does not include an IP address or a qualifying domain. For example, “\\test\test.swf ” and “file:\\test.swf” are considered local files, while “\\test.com\test.swf” and “\\192.168.0.1\test.swf ” are not considered local files.
Local SWF files from local origins, such as local file systems or UNC network paths, are placed into one of three sandboxes: local-with-networking, local-with-filesystem, and local-trusted.
When you compile the Flex application, if you set the placed in the local-with-filesystem sandbox. If you set the are placed in the local-with-networking sandbox.
Local SWF files that are registered as trusted (by users or by installer programs) are placed in the local-trusted sandbox. Users can also reassign (move) a local SWF file to or from the local-trusted sandbox based on their security considerations.
use-network compiler option to false, local SWF files are
use-network compiler option to true, local SWF files
37ADOBE FLEX 3
Page 44
CHAPTER 3
38
Deploy checklist
Before you deploy your application, ensure that your proxy servers, firewalls, and assets are configured properly. Adobe provides a deployment checklist that you can follow. For more information, see “Deployment checklist” on
page 304.
Remove wildcards
If your application relies on assets loaded from another domain, and that domain has a crossdomain.xml file on it, remove wildcards from that file if possible. For example, change the following:
<cross-domain-policy>
<allow-access-from domain="*" to-ports="*"/>
</cross-domain-policy>
to this:
<cross-domain-policy>
<allow-access-from domain="*.myserver.com" to-ports="80,443,8100,8080" />
</cross-domain-policy>
Also, set the value of the to-ports attribute of the allow-access-from tag to ensure that you are only allowing necessary ports access to the resources.
Check your application for calls to the allowDomain() and allowInsecureDomain() methods. During devel­opment, you might pass these methods a wildcard character (*), but now restrict those methods to allowing requests only from the necessary domains.
Deploy assets to WEB-INF
In some deployments, you want to make assets such as data files accessible to the application, but not accessible to anyone requesting the file. If you are using a J2EE-based server, you can deploy those files to a subdirectory within the WEB-INF directory. Based on J2EE security constraints, no J2EE server can return a resource from the WEB-INF directory to any client request. The only way to access files in this directory is with server-side code.
Precompiling source code
If you are using the Flex module for Apache and IIS, precompile MXML files, JSP files, and class files. After you precompile your MXML and JSP files, remove the source files from the public-facing server. You should not be using the Flex module for Apache and IIS to compile MXML file in a production environment.
To precompile MXML files, use the mxmlc compiler utility in the bin directory. For more information on using the utility, see “About the command-line compilers” on page 131.
To precompile JSP files on JRun, for example, you use the jspc precompiler utility located in the JRun bin directory. For information on precompiling JSP files on your application server, see your application server documentation.
Page 45
Building an d Deploying Adobe Flex 3 Applications

Loading assets

The most common task that developers perform that requires an understanding of security is loading external assets.

Data compared to content

The Flash Player security model makes a distinction between loading content and accessing or loading data. Content is defined as media: visual media that Flash Player can display, such as audio, video, or a SWF file that includes displayed media. Data is defined as something that you can manipulate only with ActionScript code.
You can load data in one of two ways: by extracting data from loaded media content, or by directly loading data from an external file (such as an XML file) or socket connection. You can extract data from loaded media by using the
BitmapData.draw() method, the Sound.id3 property, or the SoundMixer.computeSpectrum() method.
You can load data by using classes such as the SWFLoader, URLStream, URLLoader, Socket, and XMLSocket classes.
The Flash Player security model defines different rules for loading content and accessing data. Loading content has fewer restrictions than accessing data. In general, content such as SWF files, bitmaps, MP3 files, and videos can be loaded from anywhere, but if the content is from a domain other than that of the loading SWF file, it will be partitioned in a separate security sandbox.
39ADOBE FLEX 3

Loading remote assets

Loading remote or network assets relies on three factors:
Type of asset. If the target asset is a content asset, such as an image file, you do not need any specific permis-
sions from the target domain to load its assets into your Flex application. If the target asset is a data asset, such as an XML fil e, you mu st have the t arget domai n’s per mission to a ccess this asse t. For more i nfor matio n on the ty pes of assets, see
Target domain. If you are loading data assets from a different domain, the target domain must provide a cross-
domain.xml policy file. This file contains a list of URLs and URL patterns that it allows access from. The calling domain must match one of the URLs or URL patterns in that list. For more information about the cross domain.xml file, see “Using cross-domain policy files” on page 40. If the target asset is a SWF file, you can also provide permissions by calling the loadPolicyFile() method and loading an alternative policy file inside that target SWF file. For more information, see
“Data compared to content” on page 39.
-
“Using cross-domain policy files” on page 40.
Page 46
CHAPTER 3
40
Loading SWF file’s sandbox. To load an asset from a network address, you must ensure that your SWF file is
in either the remote or local-with-networking sandbox. To ensure that a SWF file can lo ad assets over the network, you must set the If the application was loaded from the local file system with
use-network compiler option to true when you compile the Flex application. This is the default.
use-network set to false, the application is put in
the local-with-filesystem sandbox and it cannot load remote SWF files.
Loading assets from a remote location that you do not control can potentially expose your users to risks. For example, the remote website B contains a SWF file that is loaded by your website A. This SWF file normally displays an advertisement. However, if website B is compromised and its SWF file is replaced with one that asks for a username and password, some users might disclose their login information. To prevent data submission, the loader has a property called
Using cross-domain policy files
allowNetworking with a default value of never.
To make data available to SWF files in different domains, use a cross-domain policy file. A cross-domain policy file is an XML file that provides a way for the server to indicate that its data and documents are available to SWF files served from other domains. Any SWF file that is served from a domain that the server’s policy file specifies is permitted to access data or assets from that server.
When a Flash document attempts to access data from another domain, Flash Player attempts to load a policy file from that domain. If the domain of the Flash document that is attempting to access the data is included in the policy file, the data is automatically accessible.
The default policy file is named crossdomain.xml and resides at the root directory of the server that is serving the data. The following example policy file permits access to Flash documents that originate from foo.com, friend­OfFoo.com, *.foo.com, and 105.216.0.40:
<?xml version="1.0"?> <!-- http://www.foo.com/crossdomain.xml --> <cross-domain-policy>
<allow-access-from domain="www.friendOfFoo.com"/> <allow-access-from domain="*.foo.com"/> <allow-access-from domain="105.216.0.40"/>
</cross-domain-policy>
You can also configure ports in the crossdomain.xml file. For more information about crossdomain.xml policy files, see Programming ActionScript 3.0.
You can use the loadPolicyFile() method to access a nondefault policy file.
Page 47
Building an d Deploying Adobe Flex 3 Applications

Loading local assets

In some cases, your SWF file might load assets that reside on the client’s local file system. This typically happens when the Flex application is embedded on the client device and loaded from a network. If the application is allowed to access local assets, it cannot access network assets.
To ensure that a Flex application can access assets in the local sandbox, the application must be in the local-with­filesystem or local-trusted sandbox. To ensure this, you set the compile the application. The default value of this option is
When you load another SWF file that is in the local file system into your application with a class such as SWFLoader, and you want to call methods or access properties of that SWF file, you do not need to explicitly enable cross-scripting.
If the SWF files are in different sandboxes (for example, you loaded the main SWF file into the local-with-network sandbox, but loaded the asset SWF file from the network), you cannot cross-script because they are in different sandboxes. Remote SWF files cannot load local SWF files, and vice versa.
use-network compiler option to false when you
true.

Using J2EE authentication

Flex applications integrates well with any server environment, including J2EE. To effectively implement secure web applications in a J2EE environment, you should understand the following concepts:
Authentication The process of gathering user credentials (user name and password) and validating them in the
system. This requires checking the credentials against a user repository such as a database, flat file, or LDAP implementation, and authenticating that the user is who they say they are.
Authorization The process of making sure that the authenticated user is allowed to view or access a given
resource. If a user is not authorized to view a resource, the container does not allow access.
41ADOBE FLEX 3

Using container-based authentication

J2EE uses the Java Authentication and Authorization Service (JAAS), Java security manager, and policy files to enforce access controls on users and ties this enforcement to web server roles. The authenticating mechanism is role based. That is, all users who access a web application are assigned to one or more roles. Example roles are manager, developer, and customer.
Application developers can assign usage roles to a web application, or to individual resources that make up the application. Before a user is granted access to a web application resource, the container ensures that the user is identified (logged in) and that the user is assigned to a role that has access to the resource. Any unauthorized access of a web application results in an HTTP 401 (Unauthorized) status code.
Page 48
CHAPTER 3
42
Authentication requires a website to store information about users. This information includes the role or roles assigned to each user. In addition, websites that authenticate user access typically implement a login mechanism that forces verification of each user’s identity by using a password. After the website validates the user, the website can then determine the user’s roles.
This logic is typically implemented in one of the following forms:
JDBC Login Module
LDAP Login Module
Windows Login Module
Custom JAAS Login Module
Authentication occurs on a per-request basis. The container typically checks every request to a web application and authenticates it.
Authentication requires that the roles that the application developer defines for a web application be enforced by the server that hosts the application.
As part of developing and deploying an application, you must configure the following application authentication settings:
Access roles to applications
Resource protection
Application server validation method
The web application’s deployment descriptor, web.xml, contains the settings for controlling application authenti­cation. This file is stored in the web application’s WEB-INF directory.
Using authentication to control access to Flex applications
To use authentication to prevent unauthorized access to your Flex application, you typically use the container to set up constraints on resources. You then challenge the user who then submits credentials. These credentials determine the success or failure of the user’s login attempt, as the container’s authentication logic determines.
For example, you can protect the page that the Flex application is returned with, or protect the SWF file itself. You do this in the web.xml file by defining specific URL patterns, as the following example shows:
<web-app>
<security-constraint>
<web-resource-collection>
<web-resource-name>Payroll Application</web-resource-name>
<url-pattern>/payroll/*</url-pattern> <http-method>GET</http-method> <http-method>POST</http-method>
</web-resource-collection>
Page 49
Building an d Deploying Adobe Flex 3 Applications
<auth-constraint>
<role-name>manager</role-name>
</auth-constraint>
</security-constraint>
</web-app>
When the browser tries to load a resource that is secured by constraints in the web.xml file, the browser either challenges the user (if you are using BASIC authentication) or forwards the user to a login page (with FORM authentication).
With BASIC authentication, the user enters a username and password in a popup box that the browser creates. To specify that an application uses BASIC authentication, you use the
login-config element and its auth-method
subelement in the web application’s web.xml file, as the following example shows:
<web-app>
<login-config>
<auth-method>BASIC</auth-method>
<realm-name>Managers</realm-name> </login-config> ...
</web-app>
With FORM authentication, you must code the page that accepts the username and password, and submit them as FORM variables named
j_username and j_password. This form can be implemented in HTML or as a Flex
application or anything that can submit a form.
When you configure FORM authentication, you can specify both a login form and an error form in the web.xml file, as the following example shows:
<web-app>
<login-config>
<auth-method>FORM</auth-method>
<form-login-config>
<form-login-page>/login.htm</form-login-page> <form-error-page>/loginerror.htm</form-error-page>
</form-login-config> </login-config>
</web-app>
43ADOBE FLEX 3
You submit the results of the form validation to the j_security_check action. The server executing the appli­cation recognizes this action and processes the form.
A simple HTML-based form might appears as follows:
<form method="POST" action="j_security_check">
<table>
<tr><td>User</td><td><input type=text name="j_username"></tr>
<tr><td>Password</td><td><input type=password name="j_password"></tr>
Page 50
CHAPTER 3
44
</table> <input type=submit>
</form>
The results are submitted to the container’s JAAS system with base-64 encoding, which means they can be read by anyone that can view the TCP/IP traffic. Use encryption to prevent these so-called “man-in-the-middle” attacks. In both BASIC and FORM authentication, if the user accessed the resource through SSL, the username and password submission are encrypted, as is all traffic during that exchange.
After it is complete, the container populates the browser’s security context and provides or denies access to the resource. Flash Player inherits the security context of the underlying browser. As a result, when you make a data service call, the established credentials are used.
When a user fails an authentication attempt with invalid credentials, be sure not to return information about which item was incorrect. Instead, use a generic message such as “Your login information was invalid.”

Using RPC services

You can use the RPC services classes—RemoteObject, HTTPService, and We b S e r vi c e —not only to control access to the data that goes into an MXML page, but also to control the data and actions that flow out of it. You can also use service authentication to allow only certain users to perform certain actions. For example, if you have an appli­cation that allows employee data to be modified through a RemoteObject call, use RemoteObject authentication to make sure that only managers can change the employee data.
A service-based architecture makes it easy to implement several different security models for your Flex appli­cation. You can use programmatic security to limit access to services, or you can apply declarative security constraints to entire services.
When accessing RPC services with Flex tags such as the Flex application’s SWF file must connect to the service directly, which means that it can encounter security-based limitations.
Destinations must be configured entirely in the Flex application; the component must communicate directly with the RPC service.
In addition, you must set the
When
use-proxy is false, one of the following must be true:
use-proxy compiler option to false when you compile the application.
The RPC is in the same domain as the Flex application that calls it.
The RPC’s host system has a crossdomain.xml file that explicitly allows access from the Flex application’s
domain.
<mx:WebService> and <mx:HTTPService> tags, your
Page 51
Building an d Deploying Adobe Flex 3 Applications

Using secured services

Secured services are services that are protected by resource constraints. The service itself behaves as a resource that needs authentication and the container defines its URL pattern as requiring authorization.
You might have a protected Flex application that calls a protected resource. In this case, with BASIC authentication and a proxied destination, the user’s credentials are passed through to the service. The user only has to log on once when they first start the Flex application, and not when the application attempts to access the service.
Without a proxy, the user is challenged to enter their credentials a second time when the application attempts to access the service.
When you use secured services, keep the following in mind:
If possible, use HTTPS for your services when you use authentication. In BASIC and custom authentication,
user names and passwords are sent in a base-64 encoding. Using base-64 encoding hides the data only from plain view; HTTPS actually encrypts the data. You can use HTTPS in these cases by making sure HTTPS is set up on your server and by adding a protocol attribute with the value domain.xml file.
To ensure that the WebService and HTTPService endpoints are secure, use a browser window to access the
URL you are trying to secure. This should always bring up a BASIC authentication prompt.
If the BASIC or custom login box appears but you can’t log in, make sure that the users and roles were added
correctly to your application server. This is often an error-prone task that is overlooked as the source of the problem.
https on the service, and by adding a cross-
45ADOBE FLEX 3

Making other connections

Flash Player can connect to servers, services, and load data from sources other than RPC services. Some of these sources have security issues that you should consider.

Using RTMP

Flash Player uses the Real-Time Messaging Protocol (RTMP) for client-server communication. This is a TCP/IP protocol designed for high-performance transmission of audio, video, and data messages. RTMP sends unencrypted data, including authentication information (such as a name and a password).
Although RTMP in and of itself does not offer security features, Flash communications applications can perform secure transactions and secure authentication through an SSL-enabled web server.
Page 52
CHAPTER 3
46
Flash Player also provides support for versions of RTMP that are tunneled through HTTP and HTTPS. RTMP refers to RTMP transmitted within an HTTP wrapper, and RTMPS is RTMP transmitted within an HTTPS wrapper.

Using sockets

Sockets let you read and write raw binary or XML data with a connected server. Sockets transmit over TCP. Because of this, Flash Player cannot take advantage of the built-in encryption capabilities of the browser. However, you can use encryption algorithms written in ActionScript to protect the data that is being communicated.
Cross-domain access to socket and XML socket connections is disabled by default. Access to socket connections in the same domain of the SWF file on ports lower than 1024 is also disabled by default. You can permit access to these connections by serving a cross-domain policy file from any of the following locations:
The same port as the main socket connection
A different port
The HTTP server on port 80 in the same domain as the socket server
For more information, see the Socket and XMLSocket classes in Flash ActionScript Language Reference.

Using the LocalConnection class

The LocalConnection class lets you develop SWF files that can send instructions to each other. LocalConnection objects can communicate only among SWF files that are running on the same client computer, but they can be running in different applications—for example, a SWF file running in a browser and a SWF file running in a projector. (A projector is a SWF file saved in a format that can run as a stand-alone application—that is, the projector doesn’t require Flash Player to be installed since it is embedded inside the executable file.)
For every LocalConnection communication, there is a sender SWF file and a listener SWF file. The simplest way to use a LocalConnection object is to allow communication only between LocalConnection objects located in the same domain because you won’t have security issues.
Applications served from different domains that need to be able to make LocalConnection calls to each other must be granted cross-domain LocalConnection permissions. To do this, the listener must allow the sender permission by using the methods.
Adobe does not recommend using the LocalConnection.allowInsecureDomain() method because allowing non-HTTPS documents to access HTTPS documents compromises the security offered by HTTPS. It is best that all Flash SWF files that make LocalConnection calls to HTTPS SWF files are served over HTTPS.
LocalConnection.allowDomain() or LocalConnection.allowInsecureDomain()
Page 53
Building an d Deploying Adobe Flex 3 Applications
For more information about using the LocalConnection class, see Programming ActionScript 3.0.
To facilitate SWF-to-SWF communication, you can also use cross-scripting. For more information, see “Cross-
scripting” on page 34.

Using SSL

A SWF file playing in a browser has many of the same security concerns as an HTML page being displayed in a browser. This includes the security of the SWF file while it is being loaded into the browser, as well as the security of communication between Flash and the server after the SWF file has loaded and is playing in the browser. In particular, data communication between the browser and the server is susceptible to being intercepted by third parties. The solution to this issue in HTML is to encrypt the communication between the client and server to make any data captured by third parties undecipherable and thus unusable. This encryption is done by using an SSL-enabled browser and server.
Because a SWF file running within a browser uses the browser for almost all of its communication with the server, it can take advantage of the browser’s built-in SSL support. This lets communication between the SWF file and the server be encrypted. Furthermore, the actual bytes of the SWF file are encrypted while they are being loaded into the browser. Thus, by playing a SWF file within an SSL-enabled browser through an HTTPS connection with the server, you can ensure that the communication between Flash Player and the server is encrypted and secure.
The one exception to this security is the way Flash Player uses persistent sockets (through the ActionScript
XMLSocket object), which does not use the browser to communicate with the server. Because of this, SWF files
that use sockets cannot take advantage of the built-in encryption capabilities of the browser. However, you can use one-way encryption algorithms written in ActionScript to encrypt the data being communicated.
MD5 is a one-way encryption algorithm described in RFC 1321. This algorithm has been ported to ActionScript, which enables developers to secure one-way data by using the MD5 algorithm before it is sent from the SWF file to the server. For more information about RFC 1321, see www.faqs.org/rfcs/rfc1321.html or www.rsase-
curity.com/rsalabs/faq/3-6-6.html.
47ADOBE FLEX 3

Using secure endpoints

To access HTTP services or web services through HTTPS, you can specify the protocols using “https” in the wsdl or
url properties; for example:
<mx:WebService url="https://myservice.com" .../> <mx:HTTPService wsdl="https://myservice.com" .../>
Page 54
CHAPTER 3
48
By default, a SWF file served over an unsecure protocol, such as HTTP, cannot access other documents served over the secure HTTPS protocol, even when those documents come from the same domain. As a result, if you loaded the SWF file over HTTP but want to connect to the service through HTTPS, you must add
secure="false" in the crossdomain.xml file on the services’s server, as the following example shows:
<cross-domain-policy>
<allow-access-from domain="*.mydomain.com" secure="false"/>
</cross-domain-policy>
If you loaded the SWF file over HTTPS, you do not have to make any changes.

Writing secure Flex applications

When you code a Flex application, keep the following topics in mind to ensure that the application you write is as secure as possible.

MXML tags with security restrictions

Some MXML tags trigger operations that require security settings. Operations that trigger security checks include:
Referencing a URL that is outside the exact domain of the application that makes a request.
Referencing an HTTPS URL when the application that makes the request is not served over HTTPS.
Referencing a resource that is in a different sandbox.
In these cases, access rights must be granted through one of the permission-granting mechanisms such as the
allowDomain() method or a crossdomain.xml file.
MXML tags that can trigger security checks include:
Any class that extends the Channel class.
RPC-related tags that use channels such as <mx:WebService>, <mx:RemoteObject>, and
<mx:HTTPService>.
Messaging tags such as <mx:Producer> and <mx:Consumer>.
The <mx:DataService> tag.
Tags that load SWF files such as <mx:SWFLoader>.
In addition to these tags and their underlying classes, many Flash classes trigger security checks including Exter-
nalInterface, Loader, NetStream, SoundMixer, URLLoader, and URLRequest.
Page 55
Building an d Deploying Adobe Flex 3 Applications

Disabling viewSourceURL

If you enabled the view source feature by setting the value of the viewSourceURL property on the
<mx:Application> tag, you must be sure to remove it before you put your application into production.
This functionality applies only to Flex Builder users.

Remove sensitive information from SWF files

Applications built with Flash share many of the same concerns and issues as web pages when it comes to protecting the security of data. Because the SWF file format is an open format, you can extract data and algorithms contained within a SWF file. This is similar to how HTML and JavaScript code can be easily viewed by users. However, SWF files make viewing the code more difficult. A SWF file is compiled and is not human-readable like HTML or JavaScript.
But security is not obtained through obscurity. A number of third-party tools can extract data from compiled SWF files. As a result, do not consider that any data, variables, or ActionScript code compiled into an application are secure. You can use a number of techniques to secure sensitive information and still make it available for use in your SWF files.
To help ensure a secure environment, use the following general guidelines:
Do not include sensitive information, such as user names, passwords, or SQL statements in SWF files.
Do not use client-side username and password checks for authentication.
Remove debug code, unused code, and comments from code before compiling to minimize the amount of
information about your application that is available to someone with a decompiler or a debugger version of Flash Player.
If your SWF file needs access to sensitive information, load the information into the SWF file from the server
at run time. The data will not be part of the compiled SWF file and thus cannot be extracted by decompiling the SWF file. Use a secure transfer mechanism, such as SSL, when you load the data.
Implement sensitive algorithms on the server instead of in ActionScript.
Use SSL whenever possible.
Only deploy your web applications from a trusted server. Otherwise, the server-side aspect of your application
could be compromised.
49ADOBE FLEX 3
Page 56
CHAPTER 3
50

Input validation

Input validation means ensuring that input is what it says it is or is what it is supposed to be. If your application is expecting name and address information, but it gets SQL commands, have a validation mechanism in your appli­cation that checks for and filters out SQL-specific characters and strings before passing the data to the execute method.
In many cases, you want users to provide input in TextInput, TextArea, and other controls that accept user input. If you use the input from these controls in operations inside the application, make sure that the input is free of possible malicious characters or code.
One approach to enforcing input validation is to use the Flex validator classes by using the or the tag for the appropriate validator type. Validators ensure that the input conforms to a predetermined pattern. For example, the NumberValidator class ensures that a string represents a valid number. This validator can ensure that the input falls within a given range (specified by the (specified by the
domain property), is non-negative (specified by the allowNegative property), and does not
minValue and maxValue properties), is an integer
exceed the specified precision.
In typical client-server environments, data validation occurs on the server after data is submitted to it from the client. One advantage of using Flex validators is that they execute on the client, which lets you validate input data before transmitting it to the server. By using Flex validators, you eliminate the need to transmit data to and receive error messages back from the server, which improves the overall responsiveness of your application.
You can also write your own ActionScript filters that remove potentially harmful code from input. Common approaches include stripping out dollar sign ($), quotation mark ("), semi-colon (;) and apostrophe (') characters because they have special meaning in most programming languages. Because Flex also renders HTML in some controls, also filter out characters that can be used to inject script into HTML, such as the left and right angle brackets (“<” and “>”), by converting these characters to their HTML entities “<” and “>”. Also filter out the left and right parentheses (“(”and “)”) by translating them to “(” and “)”, and the pound sign (“#”) and ampersand (“&”) by translating them to “#” (#) and “&” (&).
Another approach to enforcing input validation is to use strongly-typed, parameterized queries in your SQL code. This way, if someone tries to inject malicious SQL code into text that is used in a query, the SQL ser ver will reject the query.
For more information on potentially harmful characters and conversion processes, see
http://www.cert.org/tech_tips/malicious_code_mitigation.html.
For more information about validators, see “Validating Data” on page 1263 in the Adobe Flex 3 Developer Guide.
<mx:Validator> tag

ActionScript

Use some of the following techniques to try to make your use of ActionScript more secure.
Page 57
Building an d Deploying Adobe Flex 3 Applications
Handling errors
The SecurityError exception is thrown when some type of security violation takes place. Security errors include:
An unauthorized property access or method call was made across a security sandbox boundary.
An attempt was made to access a URL not permitted by the security sandbox.
A socket connection was attempted to an unauthorized port number, for example, a port below 1024, without
a policy file present.
An attempt was made to access the user’s camera or microphone, and the request to access the device was
denied by the user.
Flash Player dispatches SecurityErrorEvent objects to report the occurrence of a security error. Security error events are the final events dispatched for any target object. This means that any other events, including generic error events, are not dispatched for a target object that experiences a security error.
Your event listener can access the SecurityErrorEvent object’s
text property to determine what operation was
attempted and any URLs that were involved, as the following example shows:
<?xml version="1.0"?> <!-- security/SecurityErrorExample.mxml --> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="initApp()"> <mx:Script><![CDATA[ import flash.net.URLLoader; import flash.net.URLRequest; import flash.events.SecurityErrorEvent; import mx.controls.Alert;
51ADOBE FLEX 3
private var loader:URLLoader = new URLLoader();
private function initApp():void { loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler); }
private function triggerSecurityError():void { // This URL is purposefully broken so that it will trigger a // security error. var request:URLRequest = new URLRequest("http://www.[yourDomain].com");
// Triggers a security error. loader.load(request); }
private function securityErrorHandler(event:SecurityErrorEvent):void { Alert.show("A security error occurred! Check trace logs for details."); trace("securityErrorHandler: " + event.text);
Page 58
CHAPTER 3
52
} ]]></mx:Script>
<mx:Button id="b1" label="Click Me To Trigger Security Error" click="triggerSecurityError()"/>
</mx:Application>
If no event listeners are present, the debugger version of Flash Player automatically displays an error message that contains the contents of the text property.
In general, try to wrap methods that might trigger a security error in a try/catch block. This prevents users from seeing information about destinations or other properties that you might not want to be visible.
Suppressing debug output
Flash Player writes debug output from a trace() method or the Logging API to a log file on the client. Any client can be running the debugger version of Flash Player. As a result, remove calls to the
trace() method and Logging
API calls that produce debugging output so that clients cannot view your logged information.
If you use the Logging API in your custom components and classes, set the value of the LogEventLevel to NONE before compilation, as the following example shows:
myTraceTarget.level = LogEventLevel.NONE;
For more information about the Logging API, see “Using the logging API” on page 233.
Using host-based authentication
IP addresses and HTTP headers are sometimes used to perform host-based authentication. For example, you might check the Referer header or the client IP address to ensure that a request comes from a trusted source.
However, request headers such as Referer can be spoofed easily. This means that clients can pretend to be something they are not by settings headers or faking IP addresses. The solution to the problem of client spoofing is to not use HTTP header data as an authentication mechanism.

Using passwords

Using passwords in your Flex application is a common way to protect resources from unauthorized access. Test the validity of the password on the server rather than the client, because the client has access to all the logic in the local SWF file.
Never store passwords locally. For example, do not store username and password combinations in local Share-
dObjects. These are stored in plain-text and unencrypted, just as cookie files are. Anyone with access to the user’s
computer can access the information inside a SharedObject.
Page 59
Building an d Deploying Adobe Flex 3 Applications
To ensure that passwords are transmitted from the client to the server safely, enforce the use of SSL or some other secure transport-level protocol.
When you ask for a password in a Te x t A re a or Te x t I n p ut control, set the displayAsPassword property to true. This displays the password as asterisks as it is typed.

Storing persistent data with the SharedObject class

Flash Player supports persistent shared objects through the SharedObject class. The SharedO bjec t class stores data on users’ computers. This data is usually local, meaning that it was obtained with the method. You can also create persistent remote data with the SharedObject class; this requires Flash Media Server (formerly Flash Communication Server).
Each remote sandbox has an associated store of persistent SharedObject directory on the client. For example, when any SWF from domain1.com reads or writes data with the SharedObject class, Flash Player reads or writes that object in the domain1.com object store. Likewise for a SWF from domain2.com, Flash Player uses the domain2.com store. To avoid name collisions, the directory path defaults to the full path in the URL of the creating SWF file. This process can be shortened by using the method, which allows other SWF files from the same domain to access a shared object after it is created.
Every domain has a maximum amount of data that a SharedObject class can save in the object store. This is an allocation of the user’s disk space in which applications from that domain can store persistent data. Users can change the quota for a domain at any time by choosing Settings from the Flash Player context menu. When an application tries to store data with a SharedObject class that causes Flash Player to exceed its domain’s quota, a dialog box appears, asking the user whether to increase the domain quota.
localPath parameter of the SharedObject.getLocal()
SharedObject.getLocal()
53ADOBE FLEX 3

Configuring client security settings

Some security control features in Flash Player target user choices, and some target the modern corporate and enterprise environments, such as when the IT department would like to install Flash Player across the enterprise but has concerns about IT security and privacy. To help address these types of requirements, Flash Player provides various installation-time configuration choices. For example, some corporations do not want Flash Player to have access to the computer’s audio and video hardware; other environments do not want Flash Player to have any read or write access to the local file system.
Three groups can make security choices: the application author (using developer controls), the administrative user (using administrator controls), and the local user (with user controls).
Page 60
CHAPTER 3
54

About the mm.cfg file

You configure the debugger version of Flash Player by using the settings in the mm.cfg text file. You must create this file when you first configure the debugger version of Flash Player.
The settings in this file let you enable or disable trace() logging, set the location of the trace() file’s output, and configure client-side error and warning logging.
For more information, see “Configuring the debugger version of Flash Player” on page 229.

About the mms.cfg file

The primary purpose for the Macromedia® Security Configuration file (mms.cfg) is to support the corporate and enterprise environments where the IT department wants to install Flash Player across the enterprise, while enforcing some common global security and privacy settings (supported with installation-time configuration choices).
On operating systems that support the concept of user security levels, the file is flagged as requiring system administrator (or root) permissions to modify or delete it. The following table shows the location of the mms.cfg, depending on the operating system:
Operating System Location of mms.cfg file
Macintosh OS X /Library/Application Support/Macromedia
Windows XP/Vista C:\WINDOWS\system32\Macromed\Flash
Windows 2000 C:\WINNT\System32\Macromed\Flash
Windows 95/98/ME C:\WINDOWS\System\Macromed\Flash
Linux /etc/adobe
You can use this file to configure security settings that deal with data loading, privacy, and local file access. The settings include:
FileDownloadDisable
FileUploadDisable
LocalStorageLimit
AVHardwareDisable
For a complete list of options and their descriptions, see http://www.adobe.com/devnet/flash-
player/articles/flash_player_8_security.pdf.
Page 61
Building an d Deploying Adobe Flex 3 Applications

About FlashPlayerTrust files

Flash Player provides a way for administrative users to register certain local files so that they are always loaded into the local-trusted sandbox. Often an installer for a native application or an application that includes many SWF files will do this. Depending on whether Flash Player will be embedded in a nonbrowser application, one of two strategies can be appropriate: register SWF files and HTML files to be trusted, or register applications to be trusted. Only applications that embed the browser plug-ins can be trusted—the stand-alone players and standard browsers do not check to see if they were trusted.
The installer creates files in a directory ca lled FlashPlayerTrust. These files list paths of trusted files. This directory, known as the Global Flash Player Trust directory, is alongside the mms.cfg file, in the following location, which requires administrator access:
Windows: system\Macromed\Flash\FlashPlayerTrust (for example,
C:\winnt\system32\Macromed\Flash\FlashPlayerTrust)
OS X: app support/Macromedia/FlashPlayerTrust (for example, /Library/Application Support/Macro-
media/FlashPlayerTrust)
These settings affect all users of the computer. If an installer is installing an application for all users, the installer can register its SWF files as trusted for all users.
For more information about FlashPlayerTrust files, see http://www.adobe.com/devnet/flash-
player/articles/flash_player_8_security.pdf.
55ADOBE FLEX 3

About the Settings Manager

The Settings Manager allows the individual user to specify various security, privacy, and resource usage settings for applications executing on their client computer. For example, the user can control application access to select facilities (such as their camera and microphone), or control the amount of disk space allotted to a SWF file’s domain. The settings it manages are persistent and controlled by the user.
The user can indicate their personal choices for their Flash Player settings in a number of areas, either globally (for Flash Player itself and all applications built with Flash) or specifically (applying to specific domains only). To designate choices, the user can select from the six tab categories along the top of the Settings Manager dialog box:
Global Privacy Settings
Global Storage Settings
Global Security Settings
Flash Player Update Settings
Privacy Settings for Individual Websites
Storage Settings for Individual Websites
Page 62
CHAPTER 3
56
Access the Settings Manager for your Flash Player
1 Open an application in Flash Player.
2 Right-click and select Settings.
The Adobe Flash Player Settings dialog box appears.
3 Select the Privacy tab (on the far left).
4 Click the Advanced button.
Flash Player launches a new browser window and loads the Settings Manager help page.

Other resources

The following table lists resources that are useful in understanding the Flash Player security model and imple­menting security in your Flex applications:
Resource name Location
Security Topic Center http://www.adobe.com/devnet/security
Security Bulletins and Advisories http://www.adobe.com/support/security
Flash Player Security & Privacy http://www.adobe.com/products/flashplayer/security
Security Resource Center http://www.adobe.com/ resources/s ecurity
Flash Player 9 Security white paper http://www.adobe.com/go/fp9_0_security
“Flash Player Security” in Programming
ActionScript
“Network ing and Communicat ions” in Programming
ActionScript
Security Changes in Flash Player 8 http://ww w.adobe.com/devnet/fla sh/articles/fplayer8_security.html
Security Changes in Flash Player 7 http://www.adobe.com/devnet/flash/articles/fplayer_security.html
Understanding Service Auth entication http://www.adobe.com/devnet/flex/articles/security_framework_print.html
Settings Manager http://www.adobe.com/support/flashplayer/help/settings/
3.0
3.0.
http://www.adobe.com/go/progAS3_security
http://www.adobe.com/go/AS3_networking_and_communications
Page 63

Chapter 4: Optimizing Flex Applications

After you have a working application, you can explore ways to make that application download faster and perform better.
Top ic s
Improving client-side performance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57

Improving client-side performance

Tuning software to achieve maximum performance is not an easy task. You must commit to producing efficient implementations and monitor software performance continuously during the software development process.
Employ the following general guidelines when you test applications for performance, such as using the
getTimer() method and checking initialization time.
Before you begin actual testing, you should understand some of the influences that client settings can have on performance testing. For more information, see “Configuring the client environment” on page 62.
In addition to these techniques, you should also consider using the Adobe® Flex® profiler in Adobe® Flex® Builder™. For more information, see “Profiling Flex applications” on page 155 in Using Adobe Flex Builder 3.
57

General guidelines

You can use the following general guidelines when you improve your application and the environment in which it runs:
Set performance targets early in the software design stage. If possible, try to estimate an acceptable perfor-
mance target early in the application development cycle. Certain usage scenarios dictate the performance require­ments. It would be disappointing to fully implement a product feature and then find out that it is too slow to be useful.
Understand performance characteristics of the application framework, and employ the strategies that
maximize the efficiency of components and operations.
Understand performance characteristics of the application code. In medium-sized or large-sized projects, it is
common for a product feature to use codes or components written by other developers or by third-party vendors. Knowing what is slow and what is fast in dependent components and code is essential in getting the design right.
Page 64
CHAPTER 4
58
Do not attempt to test a large application’s performance all at once. Rather, test small pieces of the application
so that you can focus on the relevant results instead of being overwhelmed by data.
Test the performance of your application early and often. It is always best to identify problem areas early and
resolve them in an iterative manner, rather then trying to shove performance enhancements into existing, poorly performing code at the end of your application development cycle.
Avoid optimizing code too early. Even though early testing can highlight performance hot spots, refrain from
fixing them while you are still developing those areas of the application; doing so might unexpectedly delay the implementation schedule. Instead, document the issues and prioritize all the performance issues as soon as your team finishes the feature implementation.

Testing applications for performance

You can use various techniques to test start-up and run-time performance of your Flex applications, such as monitoring memory consumption, timing application initialization, and timing events. The Flex profiler provides this type of information without requiring you to write any additional code. If you are using Flex Builder, you should use the profiler for testing your application’s performance. For more information, see “Profiling Flex appli­cations” on page 155 in Using Adobe Flex Builder 3.
Calculating application initialization time
On e approach to per formanc e profiling is to use code to gauge th e star t-up time of yo ur appli cati on. Th is can help identify bottlenecks in the initialization process, and reveal deficiencies in your application design, such as too many components or too much reliance on nested containers.
The
getTimer() method in flash.utils returns the number of milliseconds that have elapsed since Adobe® Flash®
Player or Adobe AIR™ was initialized. This indicates the amount of time since the application began playing. The Timer class provides a set of methods and properties that you can use to determine how long it takes to execute an operation.
Before each update of the screen, Flash Player calls the set of functions that are scheduled for the update. Sometimes, a function should be called in the next update to allow the rest of the code scheduled for the current update to execute. You can instruct Flash Player or AIR to call a function in the next update by using the
callLater() method. This method accepts a function pointer as an argument. The method then puts the
function pointer on a queue, so that the function is called the next time the player dispatches either a or an
enterFrame event.
The following example records the time it takes the Appli cat ion object to create, measure, lay out, and draw all of its children. This example does not include the time to download the SWF file to the client, or to perform any of the server-side processing, such as checking the Flash Player version, checking the SWF file cache, and so on.
render event
Page 65
Building an d Deploying Adobe Flex 3 Applications
<?xml version="1.0"?> <!-- optimize/ShowInitializationTime.mxml --> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="callLater(showInitTime)"> <mx:Script><![CDATA[ import flash.utils.Timer;
[Bindable] public var t:String; private function showInitTime():void { // Record the number of ms since the player was initialized. t = "App startup: " + getTimer() + " ms"; } ]]></mx:Script> <mx:Label id="l1" text="{t}"/> </mx:Application>
This example uses the callLater() method to delay the recording of the startup time until after the application finishes and the first screen updates. The reason that the
callLater() method is to make sure that the application finishes initializing itself before calling the getTimer()
showInitTime function pointer is passed to the
method.
For more information on using the
callLater() method, see “Using the callLater() method” on page 107.
59ADOBE FLEX 3
Calculating elapsed time
Some operations take longer than others. Whether these operations are related to data loading, instantiation, effects, or some other factor, it’s important for you to know how long each aspect of your application takes.
You can calculate elapsed time from application startup by using the getTimer() method. The following example calculates the elapsed times for the
preinitialize and creationComplete events for all the form elements. You
can modify this example to show individual times for the initialization and creation of each form element.
<?xml version="1.0" encoding="iso-8859-1"?> <!-- optimize/ShowElapsedTime.mxml --> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" initialize="init()"> <mx:Script><![CDATA[ [Bindable] public var dp:Array = [ {food:"apple", type:"fruit", color:"red"}, {food:"potato", type:"vegetable", color:"brown"}, {food:"pear", type:"fruit", color:"green"}, {food:"orange", type:"fruit", color:"orange"}, {food:"spinach", type:"vegetable", color:"green"}, {food:"beet", type:"vegetable", color:"red"} ];
Page 66
CHAPTER 4
60
public var sTime:Number; public var eTime:Number; public var pTime:Number;
private function init():void { f1.addEventListener("preinitialize", logPreInitTime, true); f1.addEventListener("creationComplete", logCreationCompTime, true); }
private var isFirst:Boolean = true;
private function logPreInitTime(e:Event):void { // Get the time when the preinitialize event is dispatched. sTime = getTimer();
trace("Preinitialize time for " + e.target + ": " + sTime.toString()); }
private function logCreationCompTime(e:Event):void { // Get the time when the creationComplete event is dispatched. eTime = getTimer();
// Use target rather than currentTarget because these events are // triggered by each child of the Form control during the capture // phase. trace("CreationComplete time for " + e.target + ": " + eTime.toString()); }
]]></mx:Script>
<mx:Form id="f1"> <mx:FormHeading label="Sample Form" id="fh1"/> <mx:FormItem label="List Control" id="fi1"> <mx:List dataProvider="{dp}" labelField="food" id="list1"/> </mx:FormItem> <mx:FormItem label="DataGrid control" id="fi2"> <mx:DataGrid width="200" dataProvider="{dp}" id="dg1"/> </mx:FormItem> <mx:FormItem label="Date controls" id="fi3"> <mx:DateChooser id="dc"/> <mx:DateField id="df"/> </mx:FormItem> </mx:Form> </mx:Application>
Page 67
Building an d Deploying Adobe Flex 3 Applications
Calculating memory usage
You use the totalMemory property in the System class to find out how much memory has been allocated to Flash Player or AIR on the client. The
totalMemory property represents all the memory allocated to Flash Player or
AIR, not necessarily the memory being used by objects. Depending on the operating system, Flash Player or AIR will be allocated more or less resources and will allocate memory with what is provided.
You can record the value of
totalMemory over time by using a Timer class to set up a recurring interval for the
timer event, and then listening for that event.
The following example displays the total amount of memory allocated (totmem) to Flash Player at 1-second intervals. This value will increase and decrease. In addition, this example shows the maximum amount of memory that had been allocated (maxmem) since the application started. This value will only increase.
<?xml version="1.0"?> <!-- optimize/ShowTotalMemory.mxml --> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" initialize="initTimer()"> <mx:Script><![CDATA[ import flash.utils.Timer; import flash.events.TimerEvent;
[Bindable] public var time:Number = 0; [Bindable] public var totmem:Number = 0; [Bindable] public var maxmem:Number = 0;
61ADOBE FLEX 3
public function initTimer():void { // The first parameter is the interval (in milliseconds). The // second parameter is number of times to run (0 means infinity). var myTimer:Timer = new Timer(1000, 0); myTimer.addEventListener("timer", timerHandler); myTimer.start(); }
public function timerHandler(event:TimerEvent):void { time = getTimer() totmem = flash.system.System.totalMemory; maxmem = Math.max(maxmem, totmem); } ]]></mx:Script> <mx:Form> <mx:FormItem label="Time:"> <mx:Label text="{time} ms"/>
Page 68
CHAPTER 4
62
</mx:FormItem> <mx:FormItem label="totalMemory:"> <mx:Label text="{totmem} bytes"/> </mx:FormItem> <mx:FormItem label="Max. Memory:"> <mx:Label text="{maxmem} bytes"/> </mx:FormItem> </mx:Form> </mx:Application>

Configuring the client environment

When testing applications for performance, it is important to configure the client properly.
Choosing the version of Flash Player
When you test your applications for performance, use the standard version of Adobe® Flash® Player or AIR rather than the debugger version of Flash Player or ADL, if possible. The debugger version of Player provides support for the
trace() method and the Logging API. Using logging or the trace() method can significantly slow player
performance, because the player must write log entries to disk while running the application.
If you do use the debugger version of Flash Player, you can disable logging and the trace() method by setting the
TraceOutputFileEnable property to 0 in your mm.cfg file. You can keep trace() logging working, but
disable the Logging API that you might be using in your application, by setting the logging level of the TraceTarget logging target to
myLogger.log(LogEventLevel.NONE, s);
NONE, as the following example shows:
For performance testing, consider writing run-time test results to text components in the application rather than calling the
trace() method so that you can use the standard version of Flash Player and not the debugger version
of Flash Player.
For more information about configuring trace() method output and logging, see “Logging” on page 227.
Disabling SpeedStep
If you are running performance tests on a Windows laptop computer, disable Intel SpeedStep functionality. SpeedStep toggles the speed of the CPU to maximize battery life. SpeedStep can toggle the CPU at unpredictable times, which makes the results of a performance test less accurate than they would otherwise be.
1 Select Start > Settings > Control Panel.
2 Double-click the Power Settings icon.
The Power Options Properties dialog box displays.
3 Select the Power Schemes tab.
Page 69
Building an d Deploying Adobe Flex 3 Applications
4 Select High System Performance from the Power Schemes drop-down box.
5 Click OK.
Changing timeout length
When you test your application, be aware of the scriptTimeLimit property. If an application takes too long to initialize, Flash Player warns users that a script is causing Flash Player to run slowly and prompts the user to abort the application. If this is the situation, you can set the
scriptTimeLimit property of the <mx:Application> tag
to a longer time so that the Flex application has enough time to initialize.
However, the default value of the
scriptTimeLimit property is 60 seconds, which is also the maximum, so you
can only increase the value if you have previously set it to a lower value. You rarely need to change this value.
The following example sets the
<?xml version="1.0"?> <!-- optimize/ChangeScriptTimeLimit.mxml --> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" scriptTimeLimit="30"> <!-- Empty application --> </mx:Application>
scriptTimeLimit property to 30:
Preventing client-side caching
When you test performance, ensure that you are not serving files from the local cache to Flash Player. Otherwise, this can give false results about download times. Also, during development and testing, you might want to change aspects of the application such as embedded images, but the browser continues to use the old images from your cache.
If the date and time in the If-Modified-Since request header matches the date and time in the Last-Modified response header, the browser loads the SWF file from its cache. Then the server returns the 304 Not Modified message. If the Last-Modified header is more recent, the server returns the SWF file.
You can use the following techniques to disable client-side caching:
Delete the Flex files from the browser’s cache after each interaction with your application. Browsers typically
store the SWF file and other remote assets in their cache. On Microsoft Internet Explorer in Windows XP, for example, you can delete all the files in c:\Documents and Settings\username\Local Settings\Temporary Internet Files to force a refresh of the files on the next request. For more information, see
“Caching” on page 36.
Set the HTTP headers for the SWF file request in the HTML wrapper to prevent caching of the SWF file on
the client. The following example shows how to set headers that prevent caching in JSP:
// Set Cache-Control to no-cache. response.setHeader("Cache-Control", "no-cache"); // Prevent proxy caching. response.setHeader("Pragma", "no-cache");
63ADOBE FLEX 3
Page 70
CHAPTER 4
64
// Set expiration date to a date in the past. response.setDateHeader("Expires", 946080000000L); //Approx Jan 1, 2000 // Force always modified. response.header("Last-Modified", new Date());

Reducing SWF file sizes

You can improve initial user experience by reducing the time it takes to start an application. Part of this time is determined by the download process, where the SWF file is returned from the server to the client. The smaller the SWF file, the shorter the download wait. In addition, reducing the size of the SWF file also results in a shorter application initialization time. Larger SWF files take longer to unpack in Flash Player.
The mxmlc compiler includes several options that can help reduce SWF file size.
Using the bytecode optimizer
The bytecode optimizer can reduce the size of the Flex application’s SWF file by using bytecode merging and peephole optimization. Peephole optimization removes redundant instructions from the bytecode.
If you are using Flex Builder or the mxmlc command-line compiler, you can set the optimize compiler option to
true, as the following example shows:
mxmlc -optimize=true MyApp.mxml
The default value of the optimize option is true.
Disabling debugging
Disabling debugging can make your SWF files smaller. When debugging is enabled, the Flex compilers include line numbers and other navigational information in the SWF file that are only used in a debugging environment. Disabling debugging reduces functionality of the fdb command-line debugger and the debugger built into Flex Builder.
To disable debugging, set the The default value for the compc compiler is
debug compiler option to false. The default value for the mxmlc compiler is false.
true.
For more information about debugging, see “Using the Command-Line Debugger” on page 245.
Using strict mode
When you set the strict compiler option to true, the compiler verifies that definitions and package names in
import statements are used in the application. If the imported classes are not used, the compiler reports an error.
The following example shows some examples of when strict mode throws a compiler error:
package {
import flash.utils.Timer; // Error. This class is not used.
Page 71
Building an d Deploying Adobe Flex 3 Applications
import flash.printing.* // Error. This class is not used. import mx.controls.Button; // Error. This class is not used. import mx.core.Application; // No error. This class is used.
public class Foo extends Application { }
}
The strict option also performs compile-time type checking, which provides a small optimization increase in the application at run time.
The default value of the
strict compiler option is true.
Examining linker dependencies
To find w ays to reduce S WF fi le sizes, yo u can look at the list o f ActionScr ipt clas ses that are linked i nto your SWF file.
You can generate a report of linker dependen cies by setting the link-report compiler option to true. The output of this compiler option is a report that shows linker dependencies in an XML format.
The following example shows the dependencies for the ProgrammaticSkin script as it appears in the linker report:
<script name="C:\flex3sdk\frameworks\libs\framework.swc(mx/skins/ProgrammaticSkin)" mod="1141055632000" size="5807">
<def id="mx.skins:ProgrammaticSkin"/> <pre id="mx.core:IFlexDisplayObject"/> <pre id="mx.styles:IStyleable"/> <pre id="mx.managers:ILayoutClient"/> <pre id="flash.display:Shape"/> <dep id="String"/> <dep id="flash.geom:Matrix"/> <dep id="mx.core:mx_internal"/> <dep id="uint"/> <dep id="mx.core:UIComponent"/> <dep id="int"/> <dep id="Math"/> <dep id="Object"/> <dep id="Array"/> <dep id="mx.core:IStyleClient"/> <dep id="Boolean"/> <dep id="Number"/> <dep id="flash.display:Graphics"/>
</script>
65ADOBE FLEX 3
Page 72
CHAPTER 4
66
The following table describes the tags used in this file:
Tag Description
<script>
<def>
<pre>
<dep>
<ext>
Indicate s the name of a com pilation unit us ed in the creation of the applicatio n SWF file. Compi lation units must contain at least one public definition, such as a class, function, or namespace.
The name attribute shows the origin of the script, either from a source file or from a SWC file (for example, frame­works.swc).
If you set keep-generated=tr ue on the command line, all classes in the generated folder are listed as scripts in this file.
The size attribute shows the class' size, in bytes.
The mod attribute shows the time stamp when the script was created.
Indicates the name of a definition. A definition, like a script, can be a class, function, or namespace.
Indicates a definition that must be linked in to the SWF file before the current definition is linked in. This tag means prerequisite.
For class definitions, this tag shows the direct parent class (for e xample, flash.events:Event), plus all implemented inter­faces (for example, mx.core:IFlexDisplayObject and mx.managers:ILayoutClient) of the class.
Indicates other definitions that this definition depends on (for example, String, _ScrollBarStyle, and mx.core:IChildList). This is a reference to a definition that the current script requires.
Some script definitions have no dependencies, so the <script> tag might have no <dep> child tags.
Indicates a dependenc y to an asset that was not linked in. These dependencies show up in the linker report when you use the
external-librar y-path, externs, or load-externs compiler options to add assets to the SWF file.
You can examine the list of prerequisites and dependencies for your application definition. You do this by searching for your application’s root MXML file by its name; for example, MyApp.mxml. You might discover that you are linking in some classes inadvertently. When writing code, it is common to make a reference to a class but not actually require that class in your application. That reference causes the referenced class to be linked in, and it also links in all the classes on which the referenced class depends.
If you look through the linker report, you might find that you are linking in a class that is not needed. If you do find an unneeded class, try to identify the linker dependency that is causing the class to be linked in, and try to find a way to rewrite the code to eliminate that dependency.
Avoiding initializing unused classes
Some common ways to avoid unnecessary references include avoiding initializing classes you do not use and performing type-checking with the
getQualifiedClassName() method.
The following example checks if the class is a Button control. This example forces the compiler to include a Button in the SWF file, even if the child is not a Button control and the entire application has no Button controls.
Page 73
Building an d Deploying Adobe Flex 3 Applications
<?xml version="1.0"?> <!-- optimize/UnusedClasses.mxml --> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="checkChildType()"> <mx:Script><![CDATA[ import mx.controls.Button;
public function checkChildType():void { var child:DisplayObject = getChildAt(0); var childIsButton:Boolean = child is mx.controls.Button; trace("child is mx.controls.Button: " + childIsButton); // False. } ]]></mx:Script>
<!-- This control is here so that the getChildAt() method succeeds. --> <mx:DataGrid/>
</mx:Application>
You can use the getQualifiedClassName() method to accomplish the same task as the previous example. This method returns a String that you can compare to the name of a class without causing that class to be linked into the SWF.
The following example does not create a linker dependency on the Button control:
<?xml version="1.0"?> <!-- optimize/GetQualifiedClassNameExample.mxml --> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="checkChildType()"> <mx:Script><![CDATA[ public function checkChildType():void { var child:DisplayObject = getChildAt(0); var childClassName:String = getQualifiedClassName(child); var childIsButton:Boolean = childClassName == "mx.controls::Button" trace("child class name = Button " + childIsButton); } ]]></mx:Script>
67ADOBE FLEX 3
<!-- This control is here so that the getChildAt() method succeeds. --> <mx:DataGrid/>
</mx:Application>
Externalizing assets
There are various methods of externalizing assets used by your Flex applications; these include:
Using modules
Page 74
CHAPTER 4
68
Using run-time stylesheets
Using Runtime Shared Libraries (RSLs)
Loading assets at run time rather than embedding them
This section describes loading assets at run time. For information about modules and run-time stylesheets, see the Adobe Flex 3 Developer Guide. For information about RSLs, see “Using RSLs to reduce SWF file size” on
page 70.
One method of reducing the SWF file size is to externalize assets; that is, to load the assets at run time rather than embed them at compile time. You can do this with assets such as images, SWF files, and sound files.
Embedded assets load immediately, because they are already part of the Flex SWF file. However, they add to the size of your application and slow down the application initialization process. Embedded assets also require you to recompile your applications whenever your asset changes.
The following example embeds the shapes.swf file into the Flex application at compile time:
<?xml version="1.0"?> <!-- optimize/EmbedAtCompileTime.mxml --> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"> <mx:Image source="@Embed(source='../assets/butterfly.gif')"/> </mx:Application>
The following example loads the shapes.swf file into the Flex application at run time:
<?xml version="1.0"?> <!-- optimize/EmbedAtRunTime.mxml --> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"> <mx:Image source="../assets/butterfly.gif"/> </mx:Application>
The only supported image type that you cannot load at run time is SVG. Flash Player and AIR require that the compiler transcodes that file type at compile time. The player and AIR runtime cannot transcode that file type at run time.
When you load SWF files from domains that are not the same as the loading SWF file, you must use a cross­domain.xml file or other mechanism to enable the proper permissions. For more information on using the cross­domain.xml file, see “Using cross-domain policy files” on page 40.
An alternative to reducing SWF file sizes by externalizing assets is to increase the SWF file size by embedding assets. By embedding assets such as images, sounds, and SWF files, you can reduce the network bandwidth and connections. The SWF file size increases, but the application requires fewer network connections to the server.
For information on loading assets, see “Embedding Assets” on page 965 in the Adobe Flex 3 Developer Guide.
Page 75
Building an d Deploying Adobe Flex 3 Applications
Using character ranges for embedded fonts
By specifying a range of symbols that compose the face of an embedded font, you reduce the size of an embedded font. Each character in a font must be described; if you remove some of these characters, it reduces the overall size of the description information that Flex must include for each embedded font.
You can set the range of glyphs in the flex-config.xml file or in the
font-face declaration in each MXML file. You
specify individual characters or ranges of characters using the Unicode values for the characters, and you can set multiple ranges for each font declaration.
In CSS, you can set the Unicode range with the
@font-face {
src:url("../assets/MyriadWebPro.ttf"); fontFamily: myFontFamily; unicodeRange:
U+0041-U+005A, /* Upper-Case [A..Z] */
U+0061-U+007A, /* Lower-Case a-z */
U+0030-U+0039, /* Numbers [0..9] */
U+002E-U+002E; /* Period [.] */
}
unicodeRange property, as the following example shows:
In the flex-config.xml file, you can set the Unicode range with the <language-range> block, as the following example shows:
<language-range>
<lang>Latin I</lang> <range>U+0020,U+00A1-U+00FF,U+2000-U+206F,U+20A0-U+20CF,U+2100-U+2183</range>
</language-range>
69ADOBE FLEX 3
For more information, see “Using Fonts” on page 653 in the Adobe Flex 3 Developer Guide.

Using multiple SWF files

One way to reduce the size of an application’s file is to break the application up into logical parts that can be sent to the client and loaded over a series of requests rather than all at once. By breaking a monolithic application into smaller applications, users can interact with your application more quickly, but possibly experience some delays while the application is running.
One approach is to use the SWFLoader control. This technique can work with SWF files that add graphics or animations to an application, or SWF files that act as stand-alone applications inside the main application. If you import SWF files that require a large amount of user interaction, however, consider building them as custom components. SWF files produced with earlier versions of Flex or ActionScript may not work properly when loaded with the SWFLoader control.
Page 76
CHAPTER 4
70
Rather than loading SWF files into the main application with the SWFLoader control, consider having the SWF files communicate with each other as separate applications. You can do this with local SharedObjects, LocalCon-
nection objects, or with the ExternalInterface API.
Another approach to loading multiple small SWF files rather than one large one is to use the HTML wrapper to provide a framework for loading the SWF files.
Comparing dynamic and static linking
Most large applications use libraries of ActionScript classes and components. You must decide whether to use static or dynamic linking when using these libraries in your Flex applications.
When you use static linking, the compiler includes all components, classes, and their dependencies in the appli­cation SWF file when you compile the application. The result is a larger SWF file that takes longer to download but loads and runs quickly because all the code is in the SWF file. To compile your application that uses libraries and to statically link those definitions into your application, you use the
library-path and include-libraries
options to specify the locations of SWC files.
Dynamic linking is when some classes used by an application are left in an external file that is loaded at run time. The result is a smaller SWF file size for the main application, but the application relies on external files that are loaded during run time.
To dynamically link classes and components, you compile a library. You then instruct the compiler to exclude that library’s contents from the application SWF file. You must still provide link-checking at compile time even though the classes are not going to be included in the final SWF file.
You use dynamic linking by creating component libraries and compiling them with your application by using the
external-library-path, externs, or load-externs compiler options. These options instruct the compiler to
exclude resources defined by their arguments from inclusion in the application, but to check links against them and prepare to load them at run time. The dynamic linking. The
externs
option specifies an XML file that describes which classes to use for dynamic linking. This XML file has
externs option specifies individual classes or symbols for dynamic linking. The load-
the same syntax as the file produced by the
external-library-path option specifies SWC files or directories for
link-report compiler option.
For more information about linking, see “About linking” on page 196. For more information about compiler options, see “Using the Flex Compilers” on page 125.
Using RSLs to reduce SWF file size
One way to reduce the size of your application’s SWF file is by externalizing shared assets into stand-alone files that can be separately downloaded and cached on the client. These shared assets are loaded by any number of applications at run time, but must be transferred only once to the client. These shared files are known as Runtime Shared Libraries (RSLs).
Page 77
Building an d Deploying Adobe Flex 3 Applications
If you have multiple applications but those applications share a core set of components or classes, your users will be required to download those assets only once as an RSL. The applications that share the assets in the RSL use the same cached RSL as the source for the libraries as long as they are in the same domain. The resulting file size for your applications can be reduced. The benefits increase as the number of applications that use the RSL increases.
When you create an RSL, be sure to optimize it prior to deployment. This removes debugging information as well as unnecessary metadata from the RSL, which can dramatically reduce its size.
For more information, see “Using Runtime Shared Libraries” on page 195.

Application coding

The MXML language provides a rich set of controls and classes that you can use to create interactive applications. This richness sometimes can reduce performance. However, there are some techniques that a Flex developer can use to improve the run-time performance of the Flex application.
To measure the effects of the following techniques, you should use the Flex profiler. For more information, see “Profiling Flex applications” on page 155 in Using Adobe Flex Builder 3.
Object creation and destruction
Object creation is the task of instantiating all the objects in your application. These objects include controls, components, and objects that contain data and other dynamic information. Optimizing the process of object creation and destruction can result in significant performance gains. Object destruction is the act of reallocating memory for objects after all references to those objects have been removed. This task is carried out by the garbage collector at regular intervals. You can improve the frequency that Flash Player and AIR destroy objects by removing references to objects.
No single task during application initialization takes up the most time. The best way to improve performance is to create fewer objects. You can do this by deferring the instantiation of objects, or changing the order in which they are created to improve perceived performance.
71ADOBE FLEX 3
Using ordered creation
Yo u ca n i mp ro ve perceived startup time of yo ur Flex appli cation by order ing the creation of containers in the initial view. The default behavior of Flex is to create all containers and their children in the initial view, and then display everything at once. The user cannot interact with the application or see meaningful data until all the containers and their children are created.
In some cases, you can improve the user’s initial experience by displaying the components in one container before creating the components in the next container. This process is called ordered creation.
Page 78
CHAPTER 4
72
To use ordered creation, you set the creationPolicy property of a container to queued, as the following example shows:
<?xml version="1.0"?> <!-- optimize/QueuedPanels.mxml --> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"> <mx:Panel id="panel1" creationPolicy="queued" width="100%" height="33%"> <mx:Button id="button1a"/> <mx:Button id="button1b"/> </mx:Panel>
<mx:Panel id="panel2" creationPolicy="queued" width="100%" height="33%"> <mx:Button id="button2a"/> <mx:Button id="button2b"/> </mx:Panel>
<mx:Panel id="panel3" creationPolicy="queued" width="100%" height="33%"> <mx:Button id="button3a"/> <mx:Button id="button3b"/> </mx:Panel> </mx:Application>
This adds the container’s children to a queue. Flash Player instantiates and displays all of the children within the first container in the queue before instantiating the children in the next container in the queue.
For more information on ordered creation, see “Using ordered creation” on page 101.
Using deferred creation
To improve the start-up time of your application, minimize the number of objects that are created when the appli­cation is first loaded. If a user-interface component is not initially visible at start up, create that component only when you need it. This is called deferred creation. Containers that have multiple views, such as an Accordion, provide built-in support for this behavior. You can use ActionScript to customize the creation order of multiple­view containers or defer the creation of other containers and controls.
To use deferred creation, you set the value of a component’s you set it to
none, Flex does not instantiate a control’s children immediately, but waits until you instruct Flex to
creationPolicy property to all, auto, or none. If
do so. In the following example, the children of the VBox container are not be instantiated when the application is first loaded, but only after the user clicks the button:
<?xml version="1.0"?> <!-- optimize/CreationPolicyNone.mxml --> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"> <mx:Script><![CDATA[
private function createButtons(e:Event):void { myVBox.createComponentsFromDescriptors();
Page 79
Building an d Deploying Adobe Flex 3 Applications
}
]]></mx:Script>
<mx:Panel title="VBox with Repeater"> <mx:VBox id="myVBox" height="100" width="125" creationPolicy="none"> <mx:Button id="b1" label="Hurley"/> <mx:Button id="b2" label="Jack"/> <mx:Button id="b3" label="Sawyer"/> </mx:VBox> </mx:Panel>
<mx:Button id="myButton" click="createButtons(event)" label="Create Buttons"/>
</mx:Application>
You call methods such as createComponentFromDescriptor() and createComponentsFromDescriptor() on the container to instantiate its children at run time. For more information on using deferred instantiation, see
“Using deferred creation” on page 94.
Destroying unused objects
Flash Player provides built-in garbage collection that frees up memory by destroying objects that are no longer used. To ensure that the garbage collector destroys your unused objects, remove all references to that object, including the parent’s reference to the child.
For more information about garbage collection, see “About garbage collection” on page 178 in Using Adobe Flex Builder 3.
On containers, you can call the
removeChild() or removeChildAt() method to remove references to child
controls that are no longer needed. The following example removes references to button instances from the myVBox control:
<?xml version="1.0"?> <!-- optimize/DestroyObjects.mxml --> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"> <mx:Script><![CDATA[ private function destroyButtons(e:Event):void { myVBox.removeChild(b1); myVBox.removeChild(b2); myVBox.removeChild(b3); } ]]></mx:Script>
73ADOBE FLEX 3
<mx:Panel title="VBox with Repeater"> <mx:VBox id="myVBox" height="100" width="125"> <mx:Button id="b1" label="Hurley"/>
Page 80
CHAPTER 4
74
<mx:Button id="b2" label="Jack"/> <mx:Button id="b3" label="Sawyer"/> </mx:VBox> </mx:Panel>
<mx:Button id="myButton2" click="destroyButtons(event)" label="Destroy Buttons"/>
</mx:Application>
You can clear references to unused variables by setting them to null in your ActionScript; for example:
myDataProvider = null
To ensure that destroyed objects are garbage collected, you must also remove event listeners on them by using the
removeEventListener() method, as the following example shows:
<?xml version="1.0"?> <!-- optimize/RemoveListeners.mxml --> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="initApp(event)"> <mx:Script><![CDATA[ private function initApp(e:Event):void { b1.addEventListener("click",myClickHandler); b2.addEventListener("click",myClickHandler); b3.addEventListener("click",myClickHandler); }
private function destroyButtons(e:Event):void { b1.removeEventListener("click",myClickHandler); b2.removeEventListener("click",myClickHandler); b3.removeEventListener("click",myClickHandler);
myVBox.removeChild(b1); myVBox.removeChild(b2); myVBox.removeChild(b3); }
private function myClickHandler(e:Event):void { // Do something here. } ]]></mx:Script>
<mx:Panel title="VBox with Repeater"> <mx:VBox id="myVBox" height="100" width="125"> <mx:Button id="b1" label="Hurley"/> <mx:Button id="b2" label="Jack"/> <mx:Button id="b3" label="Sawyer"/> </mx:VBox>
Page 81
Building an d Deploying Adobe Flex 3 Applications
</mx:Panel>
<mx:Button id="myButton" click="destroyButtons(event)" label="Destroy Buttons"/>
</mx:Application>
You cannot call the removeEventListener() method on an event handler t hat you added inline. In the following example, you cannot call
removeEventListener() on b1’s click event handler, but you can call it on b2’s and
b3’s event handlers:
<?xml version="1.0"?> <!-- optimize/RemoveSomeListeners.mxml --> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="initApp(event)"> <mx:Script><![CDATA[ private function initApp(e:Event):void { b2.addEventListener("click",myClickHandler); b3.addEventListener("click",myClickHandler); }
private function destroyButtons(e:Event):void { b2.removeEventListener("click",myClickHandler); b3.removeEventListener("click",myClickHandler);
myVBox.removeChild(b1); myVBox.removeChild(b2); myVBox.removeChild(b3); }
private function myClickHandler(e:Event):void { // Do something here. } ]]></mx:Script>
75ADOBE FLEX 3
<mx:Panel title="VBox with Repeater"> <mx:VBox id="myVBox" height="100" width="125"> <mx:Button id="b1" label="Hurley" click="myClickHandler(event)"/> <mx:Button id="b2" label="Jack"/> <mx:Button id="b3" label="Sawyer"/> </mx:VBox> </mx:Panel>
<mx:Button id="myButton" click="destroyButtons(event)" label="Destroy Buttons"/>
</mx:Application>
Page 82
CHAPTER 4
76
The weakRef parameter to the addEventListener() method provides you with some control over memory resources for listeners. A strong reference (when collected. A weak reference (when
For more information about the
weakRef is true) does not. The default is false.
removeEventListener() method, see “Using Events” on page 61 in the Adobe
weakRef is false) prevents the listener from being garbage
Flex 3 Developer Guide.
Using styles
You use styles to define the look and feel of your Flex applications. You can use them to change the appearance of a single component, or apply them globally. Be aware that some methods of applying styles are more expensive than others. You can increase your application’s performance by changing the way you apply styles.
For more information about using styles, see “Using Styles and Themes” on page 589 in the Adobe Flex 3 Developer Guide.
Loading stylesheets at run time
You can load stylesheets at run time by using the StyleManager. These style sheets take the form of SWF files that are dynamically loaded while your Flex application runs.
By loading style sheets at run time, you can load images (for graphical skins), fonts, type and class selectors, and programmatic skins into your Flex application without embedding them at compile time. This lets skins and fonts be partitioned into separate SWF files, away from the main application. As a result, the application’s SWF file size is smaller, which reduces the initial download time. However, the first time a run-time style sheet is used, it takes longer for the styles and skins to be applied because Flex must download the necessary CSS-based SWF file.
For more information, see the Adobe Flex 3 Developer Guide.
Reducing calls to the setStyle() method
Run-time cascading styles are very powerful, but use them sparingly and in the correct context. Calling the
setStyle() method can be an expensive operation because the call requires notifying all the children of the
newly-styled object. The resulting tree of children that must be notified can be quite large.
A common mistake that impacts performance is overusing or unnecessarily using the general, you only use the set up styles for an object for the first time. Instead, set styles in an
setStyle() metho d when you change sty les on exist ing obje cts . Do no t use it w hen yo u
<mx:Style> block, as style properties on the
setStyle() method. In
MXML tag, through an external CSS style sheet, or as global styles.
Page 83
Building an d Deploying Adobe Flex 3 Applications
Some applications must call the setStyle() method during the application or object instantiation. If this is the case, call the styles from the component or application’s
creationComplete event. By setting the styles as early as possible during initialization, you avoid unnecessary
setStyle() method early in the instantiation phase. Early in the instantiation phase means setting
preinitialize event, instead of the initialize or
style notification and lookup.
If you programmatically create a component and want to set styles on that component, call the method before you attach it to the display list with a call to the
addChild() method, as the following example
setStyle()
shows:
<?xml version="1.0"?> <!-- optimize/CreateStyledButton.mxml --> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="initApp(event)"> <mx:Script><![CDATA[ import mx.controls.Button;
public function initApp(e:Event):void { var b:Button = new Button(); b.label="Click Me"; b.setStyle("color", 0x00CCFF); panel1.addChild(b); } ]]></mx:Script>
<mx:Panel id="panel1"/>
</mx:Application>
77ADOBE FLEX 3
Setting global styles
Changing global styles (changing a CSS ruleset that is associated with a class or type selector) at run time is an expensive operation. Any time you change a global style, Flash Player must perform the following actions:
Traverse the entire application looking for instances of that control.
Check all the control’s children if the style is inheriting.
Redraw that control.
The following example globally changes the Button control’s color style property:
<?xml version="1.0"?> <!-- optimize/ApplyGlobalStyles.mxml --> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="initApp(event)"> <mx:Script><![CDATA[ public function initApp(e:Event):void {
Page 84
CHAPTER 4
78
StyleManager.getStyleDeclaration("Button").setStyle("color", 0x00CCFF); } ]]></mx:Script>
<mx:Panel id="panel1"> <mx:Button id="b1" label="Click Me"/> <mx:Button id="b2" label="Click Me"/> <mx:Button id="b3" label="Click Me"/> </mx:Panel>
</mx:Application>
If possible, set global styles at authoring time by using CSS. If you must set them at run time, try to set styles by using the techniques described in “Reducing calls to the setStyle() method” on page 76.
Calling the setStyleDeclaration() and loadStyleDeclarations() met hods
The setStyleDeclaration() method is computationally expensive. You can prevent Flash Player from applying or clearing the new styles immediately by setting the
update parameter to false.
The following example sets new class selectors on different targets, but does not trigger the update until the last style declaration is applied:
<?xml version="1.0"?> <!-- styles/SetStyleDeclarationExample.mxml --> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="initApp()"> <mx:Script><![CDATA[ import mx.styles.StyleManager;
private var myButtonStyle:CSSStyleDeclaration = new CSSStyleDeclaration('myButtonStyle'); private var myLabelStyle:CSSStyleDeclaration = new CSSStyleDeclaration('myLabelStyle'); private var myTextAreaStyle:CSSStyleDeclaration = new CSSStyleDeclaration('myTextAreaStyle');
private function initApp():void { myButtonStyle.setStyle('color', 'blue'); myLabelStyle.setStyle('color', 'blue'); myTextAreaStyle.setStyle('color', 'blue'); }
private function applyStyles():void { StyleManager.setStyleDeclaration("Button", myButtonStyle, false); StyleManager.setStyleDeclaration("Label", myLabelStyle, false); StyleManager.setStyleDeclaration("TextArea", myTextAreaStyle, true); }
Page 85
Building an d Deploying Adobe Flex 3 Applications
]]></mx:Script>
<mx:Button id="myButton" label="Click Me" click="applyStyles()"/> <mx:Label id="myLabel" text="This is a label"/> <mx:TextArea id="myTextArea" text="This is a TextArea"/>
</mx:Application>
When you pass false for the update parameter, Flash Player stores the selector but does not apply the style. When you pass
true for the update parameter, Flash Player recomputes the styles for every visual component in
the application.
The
loadStyleDeclarations() method is similarly computationally expensive. When you load a new style
sheet, this method triggers an update to the display list by default. You can prevent Flash Player from applying or clearing the new style sheets immediately by setting the
loadStyleDeclarations() methods, set the update parameter to false for all calls except the last one.
update parameter to false. When you chain calls to
Working with containers
Containers provide a hierarchical structure that lets you control the layout characteristics of container children. You can use containers to control child sizing and positioning, or to control navigation among multiple child containers.
When you develop your Flex application, try to minimize the number of containers that you use. This is because most containers provide relative sizing and positioning, which can be resource-intensive operations, especially when an application first starts.
One common mistake is to create a container that contains a single child. Sometimes having a single child in a container is necessary, such as when you use the container’s padding to position the child. But try to identify and remove containers such as these that provide no real functionality. Also keep in mind that the root of an MXML component does not need to be a container.
Another sign of possibly too many containers is when you have a container nested inside another container, where both the parent and child containers have the same type (for example, HBoxes).
79ADOBE FLEX 3
Minimizing container nesting
It is good practice to avoid deeply nested layouts when possible. For simple applications, if you have nested containers more than three levels deep, you can probably produce the same layout with fewer levels of containers. Deep nesting can lead to performance problems. For larger applications, deeper nesting might be unavoidable.
Page 86
CHAPTER 4
80
When you nest containers, each container instance runs measuring and sizing algorithms on its children (some of which are containers themselves, so this measuring procedure can be recursive). When the layout algorithms have processed, and the relative layout values have been calculated, Flash Player draws the complex collection of objects comprising the view. By eliminating unnecessary work at object creation time, you can improve the perfor­mance of your application.
Using Grid containers
A Grid container is useful for aligning multiple objects. When you use Grid containers, however, you introduce additional levels of containers with the GridItem and GridRow controls. In many cases, you can achieve the same results by using the VBox and HBox containers, and these containers use fewer levels of nesting.
Using layout containers
You can sometimes improve application start-up time by using Canvas containers, which perform absolute positioning, instead of relative layout containers, such as the Form, HBox, VBox, Grid, and Tile containers.
Canvas containers are the only containers that let you specify the location of their child controls by default. All other containers are relative containers by default, which means that they lay everything out relative to other components in the container. You can make Application and Panel containers do absolute positioning.
Canvas containers eliminate the layout logic that other containers use to perform automatic positioning of their children at startup, and replace it with explicit pixel-based positioning. When you use a Canvas container, you must remember to set the x and y positions of all of its children. If you do not set the x and y positions, the Canvas container’s children lay out on top of each other at the default x, y coordinates (0,0).
The canvas container is not always more efficient than other containers, however, because it must measure itself to ma ke sure t hat it is la rge enough to c ontain its child ren. Applications th at use canvase s typi cally cont ain a much flatter containment hierarchy. As a result, using canvas containers can lead to less nesting and fewer overall containers, which improves performance.
Canvas containers support constraints, which means that if the container changes size, the children inside the container move with it.
Using absolute sizing
Writing object widths and heights into the code can save time because the Flex layout containers do not have to calculate the size of the object at run time. By specifying container or control widths or heights, you lighten the relative layout container’s processing load and subsequently decrease the creation time for the container or control. This technique works with any container or control.
Page 87
Building an d Deploying Adobe Flex 3 Applications
Improving effect performance
Effects let you add animation and motion to your application in response to user or programmatic action. For example, you can use effects to cause a dialog box to bounce slightly when it receives focus, or to slowly fade in when it becomes visible.
Effects can be one of the most processor-intensive tasks performed by a Flex application. Use the techniques described in this section to improve the performance of effects. For more information, see “Using Behaviors” on
page 545 in the Adobe Flex 3 Developer Guide.
Increasing effect duration
Increase the duration of your effect with the duration property. Doing this spreads the distinct, choppy stages over a longer period of time, which lets the human eye fill in the difference for a smoother effect.
Hiding parts of the target view
Make parts of the target view invisible when the effect starts, play the effect, and then make those parts visible when the effect has completed. To do this, you add logic in the
effectStart and effectEnd event handlers that
controls what is visible before and after the effect.
When you apply a Resize effect to a Panel container, for example, the measurement and layout algorithm for the effect executes repeatedly over the duration of the effect. When a Panel container has many children, the animation can be jerky because Flex cannot update the screen quickly enough. Also, resizing one Panel container often causes other Panel containers in the same view to resize.
To solve this problem, you can use the Resize effect’s Panel containers while the Resize effect is playing. The value of the
hideChildrenTargets property to hide the children of
hideChildrenTargets property is an Array
of Panel containers that should include the Panel containers that resize during the animation. When the
hideChildrenTargets property is true, and before the Resize effect plays, Flex iterates through the Array and
hides the children of each of the specified Panel containers.
81ADOBE FLEX 3
Avoiding bitmap-based backgrounds
Designers often give their views background images that are solid colors with gradients, slight patterns, and so forth. To ease what Flash Player redraws during an effect, try using a solid background color for your background image. Or, if you want a slight gradient instead of a solid color, use a background image that is a SWF or SVG file. These are easier for Flash Player to redraw than standard JPG or PNG files.
Page 88
CHAPTER 4
82
Suspending background processing
To improve the performance of effects, you can disable background processing in your application for the duration of the effect by setting the
suspendBackgroundProcessing property of the Effect to true. The
background processing that is blocked includes component measurement and layout, and responses to data services for the duration of the effect.
Using the cachePolicy proper ty
An effect can use bitmap caching in Flash Player to speed up animations. An effect typically uses bitmap caching when the target component’s drawing does not change while the effect is playing.
The cachePolicy property of UIComponents controls the caching operation of a component during an effect. The
cachePolicy property can have the following values:
Cach ePolicy.ON Specifies that the effect target is always cached.
Cach ePolicy.OFF Specifies that the effect target is never cached.
Cach ePolic y.AUTO Specifies that Flex determines whether the effect target should be cached. This is the default
value.
The cachePolicy property is useful when an object is included in a redraw region but the object does not change. For more information about redraw regions, see “Understanding redraw regions” on page 83.
The
cachePolicy property provides a wrapper for the cacheAsBitmap property. For more information, see
“Using the cacheAsBitmap property” on page 83.
Improving rendering speed
The actual rendering of objects on the screen can take a significant amount of time. Improving the rendering times can dramatically improve your application’s performance. Use the techniques in this section to help improve rendering speed. In addition, use the techniques described in the previous section, “Improving effect perfor-
mance” on page 81, to improve effect rendering speed.
Setting movie quality
You can use the quality property of the wrapper’s <object> and <embed> tags to change the rendering of your Flex application in Flash Player. Valid values for the
autohigh, and best. The default value is best.
quality property are low, medium, high, autolow,
Page 89
Building an d Deploying Adobe Flex 3 Applications
The low setting favors playback speed over appearance and never uses anti-aliasing. The autolow setting empha­sizes speed at first but improves appearance whenever possible. The and appearance equally at first, but sacrifices appearance for playback speed if necessary. The applies some anti-aliasing and does not smooth bitmaps. The and always applies anti-a liasing . The
best setting provides the best display quality and does not consider playback
autohigh setting emphasizes playback speed
medium setting
high setting favors appearance over playback speed
speed. All output is anti-aliased and all bitmaps are smoothed.
For information on these settings, see “About the object and embed tags” on page 321.
Understanding redraw regions
A redraw region is the region around an object that must be redrawn when that object changes. Everything in a redraw region is redrawn during the next rendering phase after an object changes. The area that Flash Player redraws includes the object, and any objects that overlap with the redraw region, such as the background or the object’s container.
You can see redraw regions at run time in the debugger version of Flash Player by selecting View > Show Redraw Regions in the player’s menu. When you select this option, the debugger version of Flash Player draws red rectangles around each redraw region while the application runs.
By looking at the redraw regions, you can get a sense of what is changing and how much rendering is occurring while your application runs. Flash Player sometimes combines the redraw regions of several objects into a single region that it redraws. As a result, if your objects are spaced close enough together, they might be redrawn as part of one region, which is better than if they are redrawn separately. If the number of regions is too large, Flash Player might redraw the entire screen.
83ADOBE FLEX 3
Using the cacheAsBitmap property
To improve rendering speeds, make careful use of the cacheAsBitmap property. You can set this property on any
UIComponent.
When you set the
cacheAsBitmap property to true, Flash Player stores a copy of the initial bitmap image of an
object in memory. If you later need that object, and the object’s properties have not changed, Flash Player uses the cached version to redraw the object. This can be faster than using the vectors that make up the object.
Setting the
cacheAsBitmap property to true can be especially useful if you use animations or other effects that
move objects on the screen. Instead of redrawing the object in each frame during the animation, Flash Player can use the cached bitmap.
The downside is that changing the properties of objects that are cached as bitmaps is more computationally expensive. Each time you change a property that affects the cached object’s appearance, Flash Player must remove the old bitmap and store a new bitmap in the cache. As a result, only set the
cacheAsBitmap property to true for
objects that do not change much.
Page 90
CHAPTER 4
84
Enable bitmap caching only when you need it, such as during the duration of an animation, and only on a few objects at a time because it can be a memory-intensive operation. The best approach might be to change this property at various times during the object’s life cycle, rather than setting it once.
Using filte rs
To improve rendering speeds, do not overuse filters such as DropShadowFilter. The expense of the filter is propor­tional to the number of pixels in the object that you are applying the filter to. As a result, it is best to use filters on smaller objects.
Using device text
Mixing device text and vector graphics can slow rendering speeds. For example, a DataGrid control that contains both text and graphics inside a cell will be much slower to redraw than a DataGrid that contains just text.
Using clip masks
Using th e scrollRect and mask properties of an object are expensive operations. Try to minimize the number of times you use these properties.
Using large data sets
You can minimize overhead when working with large data sets.
Paging
When you use a DataService class to get your remote data, you might have a collection that does not initially load all of its data on the client. You can prevent large amounts of data from traveling over the network and slowing down your application while that data is processed using paging. The data that you get incrementally is referred to as paged data, and the data that has not yet been received is pending data.
Paging data using the DataService class provides the following benefits:
Maximum message size on the destination can be configured.
If size exceeds the maximum value, multiple message batches are used.
Client reassembles separate messages.
Asynchronous data paging across the network.
User interface elements can display portions of the collection without waiting for the entire collection to load.
For more information, see “Using Data Providers and Collections” on page 137 in the Adobe Flex 3 Developer Guide.
Page 91
Building an d Deploying Adobe Flex 3 Applications
Disabling live scrolling
Using a DataGrid control with large data sets might make it slow to scroll when using the scrollbar. When the DataGrid displays newly visible data, it calls the
getItemAt() method on the data provider.
The default behavior of a DataGrid is to continuously update data when the user is scrolling through it. As a result, performance can degrade if you just simply scroll through the data on a DataGrid because the DataGrid is contin­uously calling the
getItemAt() method. This can be a computationally expensive method to call.
Yo u ca n di sab l e t hi s live scrolling so that the view is only updated when the scrolling stops by setting the
liveScrolling property to false.
The default value of the
liveScrolling property is true. A ll subclasses of ScrollControlBase, including Te xt A re a,
HorizontalList, TileList, and DataGrid, have this property.
Dynamically repeating components
There are relative benefits of using List-based controls (rather than the Repeater control) to dynamically repeat components. If you must use the Repeater, however, there are techniques for improving the performance of that control.
Comparing List-based controls to the Repeater control
To dynamically repeat components, you can choose between the Repeater or List-based controls, such as Horizon-
talList, TileList, or List. To achieve better performance, you can often replace layouts you created with a Repeater
with the combination of a HorizontalList or TileList and an item renderer.
The Repeater object is useful for repeating a small set of simple user interface components, such as RadioButton controls and other controls typically used in Form containers. You can use the HorizontalList, TileList, or List control when you display more than a few repeated objects.
The HorizontalList control displays data horizontally, similar to the HBox container. The HorizontalList control always displays items from left to right. The TileList control displays data in a tile layout, similar to the Tile container. The TileList control provides a direction property that determines if the next item is down or to the right. The List control displays data in a single vertical column.
Unlike the Repeater object, which instantiates all objects that are repeated, the HorizontalList, TileList, and List controls only instantiate what is visible in the list. The Repeater control takes a data provider (typically an Array) that creates a new copy of its children for each entry in the Array. If you put the Repeater control’s children inside a container that does not use deferred instantiation, your Repeater control might create many objects that are not initially visible.
For example, a VBox container creates all objects within itself when it is first created. In the following example, the Repeater control creates all the objects whether or not they are initially visible:
<?xml version="1.0"?>
85ADOBE FLEX 3
Page 92
CHAPTER 4
86
<!-- optimize/VBoxRepeater.mxml --> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script><![CDATA[ import mx.collections.ArrayCollection;
[Bindable] public var imgList:ArrayCollection = new ArrayCollection([ {img:"../assets/butterfly.gif"}, {img:"../assets/butterfly-gray.gif"}, {img:"../assets/butterfly-silly.gif"} ]);
]]></mx:Script>
<mx:Panel title="VBox with Repeater"> <mx:VBox height="150" width="250"> <mx:Repeater id="r" dataProvider="{imgList}"> <mx:Image source="../assets/{r.currentItem.img}"/> </mx:Repeater> </mx:VBox> </mx:Panel>
</mx:Application>
If you use a List-based control, however, Flex only creates those controls in the list that are initially visible. The following example uses the List control to create only the image needed for rendering:
<?xml version="1.0"?> <!-- optimize/ListItems.mxml --> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"> <mx:Script><![CDATA[ import mx.collections.ArrayCollection;
private static var birdList:Array = ["../assets/butterfly.gif","../assets/butterfly-gray.gif","../assets/butterfly­silly.gif"]; [Bindable] private var birdListAC:ArrayCollection = new ArrayCollection(birdList);
private function initCatalog():void { birdlist.dataProvider = birdListAC; }
]]></mx:Script>
<mx:Panel title="List">
Page 93
Building an d Deploying Adobe Flex 3 Applications
<mx:List id="birdlist" rowHeight="150" width="250" rowCount="1" itemRenderer="mx.controls.Image" creationComplete="initCatalog()"> </mx:List> </mx:Panel> </mx:Application>
Using the Repeater control
When using a Repeater control, keep the following techniques in mind:
Avoid repeating objects that have clip masks because using clip masks is a resource- intensive process.
Ensure that the containers used as the children of the Repeater control do not have unnecessary container
nesting and are as small as possible. If a single instance of the repeated view takes a noticeable amount of time to instantiate, repeating makes it worse. For example, multiple Grid containers in a Repeater object do not perform well because Grid containers themselves are resource-intensive containers to instantiate.
Set the recycleChildren property to true. The recycleChildren property is a Boolean value that, when
set to
true, binds new data items into existing Repeater children, incrementally creates children if there are more
data items, and destroys extra children that are no longer required.
The default value of the recycleChildren property is false to ensure that you do not leave stale state infor- mation in a repeated instance. For example, suppose you use a Repeater object to display photo images and each Image control has an associated NumericStepper control for how many prints you want to order. Some of the state information, such as the image, comes from the such as the print count, is set by user interaction. If you set the through the photos by incrementing the Repeater object's
dataProvider property. Other state information,
recycleChildren property to true and page
startingIndex value, the Image controls bind to
the new images, but the NumericStepper control maintains the old information. Use
recycleChildren="false" only if it is too cumbersome to reset the state information manually, or if you
are confident that modifying your
dataProvider property should not trigger a recreation of the Repeater
object’s children.
Keep in mind that the recycleChildren property has no effect on a Repeater object’s speed when the Repeater object loads the first time. The
recycleChildren property improves performance only for subse-
quent changes to the Repeater control’s data provider. If you know that your Repeater object creates children only once, you do not have to use the
recycleChildren property or worry about the stale state situation.
87ADOBE FLEX 3
Page 94
CHAPTER 4
88

Improving charting component performance

You can use various techniques to improve the performance of charting controls.

Avoiding filtering series data

When possible, set the filterData property to false. In the transformation from data to screen coordinates, the various series types filter the incoming data to remove any missing values that are outside the range of the chart; missing values would render incorrectly if drawn to the screen. For example, a chart that represents vacation time for each week in 2003 might not have a value for the July fourth weekend because the company was closed. If you know your data model will not have any missing values at run time, or values that fall outside the chart’s data range, you can instruct a series to explicitly skip the filtering step by setting its

Coding the LinearAxis object

If possible, do not let a LinearAxis object autocalculate its range. A LinearAxis control calculating its numeric range can be a resource-intensive calculation. If you know reasonable minimum and maximum values for the range of your LinearAxis, specify them to help your charts render more quickly.
In addition to specifying the range for a LinearAxis, specify an interval (the numeric distance between label values along the axis) value. Otherwise, the chart control must calculate this value.
filterData property to false.

Coding the CategoryAxis object

Modifying a CategoryAxis object’s data provider is more resource intensive than modifying a Series object’s data provider. If the data bound to your chart is going to change, but the categories in your chart will stay static, have the CategoryAxis’ data provider and Series’ data provider refer to different objects. This prevents the Catego­ryAxis from reevaluating its data provider, which is a resource-intensive computation.

Styling AxisRenderer objects

Improve the rendering time of your AxisRenderers objects by setting particular styles. The AxisRenderers perform many calculations to ensure that they render correctly in all situations. The more help you can give them in restricting their options, the faster they render. Setting the AxisRenderer improve performance. You can set these styles within the tag or in CSS.
labelRotation and canStagger styles on the
Page 95
Building an d Deploying Adobe Flex 3 Applications

Specifying gutter styles

Specify gutter styles when possible. The gutter area of a Cartesian chart is the area between the margins and the actual axis lines. With default values, the chart adjusts the gutter values to accommodate axis decorations. Calcu­lating these gutter values can be resource intensive. By explicitly setting the values of the
gutterRight, gutterTop, and gutterBottom style properties, your charts draw quicker and more efficiently.
gutterLeft,

Using drop shadows

To improve performance, do not use drop-shadows on your series items unless they are necessary. You can selec­tively add shadows to individual chart series by using renderers such as the ShadowBoxItemRenderer and
ShadowLineRenderer classes.
Shadows are implemented as filters in charting controls. As a result, you must remove these shadows by setting the chart control’s from all series, but then changes the renderer for the third series to be a shadow renderer:
<?xml version="1.0"?> <!-- optimize/RemoveShadowsColumnChart.mxml --> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"> <mx:Script><![CDATA[ import mx.collections.ArrayCollection; [Bindable] public var expenses:ArrayCollection = new ArrayCollection([ {Month: "Jan", Income: 2000, Expenses: 1500, Profit: 500}, {Month: "Feb", Income: 1000, Expenses: 200, Profit: 800}, {Month: "Mar", Income: 1500, Expenses: 500, Profit: 1000} ]); ]]></mx:Script> <mx:Panel title="Column Chart"> <mx:ColumnChart id="myChart" dataProvider="{expenses}"> <mx:seriesFilters> <mx:Array/> </mx:seriesFilters> <mx:horizontalAxis> <mx:CategoryAxis dataProvider="{expenses}" categoryField="Month"/> </mx:horizontalAxis> <mx:series> <mx:ColumnSeries xField="Month" yField="Income" displayName="Income"/> <mx:ColumnSeries xField="Month" yField="Expenses" displayName="Expenses"/> <mx:ColumnSeries xField="Month" yField="Profit" displayName="Profit" itemRenderer="mx.charts.renderers.ShadowBoxItemRenderer"/> </mx:series> </mx:ColumnChart> <mx:Legend dataProvider="{myChart}"/>
seriesFilters property to an empty Array. The following example removes the shadows
89ADOBE FLEX 3
Page 96
CHAPTER 4
90
</mx:Panel> </mx:Application>
Page 97

Chapter 5: Improving Startup Performance

Adobe® Flex® helps you improve the actual and perceived startup times of your Flex applications. You can do this by deferring the creation of certain controls until a later time, or customize the order in which containers are created and displayed in your applications.
Top ic s
About startup performance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
About startup order . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
Using deferred creation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
Creating deferred components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .98
Using ordered creation. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .101
Using the callLater() method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .107
91

About startup performance

You could increase the startup time and decrease performance of your applications if you create too many objects or put too many objects into a single view. To improve startup time, minimize the number of objects that are created when the application is first loaded. If a user-interface component is not initially visible at startup, avoid creating that component until you need it. This is called deferred creation. Containers that have multiple views, such as an Accordion container, provide built-in support for this behavior. You can use ActionScript to customize the creation order of multiple-view containers or defer the creation of other containers and controls.
After you improve the actual startup time of your application as much as possible, you can improve perceived startup time by ordering the creation of containers in the initial view. The default behavior of Flex is to create all containers and their children in the initial view, and then display everything at one time. The user will not be able to interact with the application or see meaningful data until all the containers and their children are created. In some cases, you can improve the user’s initial experience by displaying the components in one container before creating the components in the next container. This process is called ordered creation.
Page 98
CHAPTER 5
preinitialize
initialize
creationComplete
updateComplete
92
The remaining sections of this topic describe how to use deferred creation to reduce overall application startup time and ordered creation to make the initial startup time appear as short as possible to the user. But before you can fully understand ordered creation and deferred creation, you must also understand the differences between single-view and multiple-view containers, the order of events in a component’s startup life cycle, and how to manually instantiate controls from their child descriptors.

About startup order

All Flex components trigger a number of events during their startup procedure. These events indicate when the component is first created, plotted internally, and drawn on the screen. The events also indicate when the component is finished being created and, in the case of containers, when its children are created.
Components are instantiated, added or linked to a parent, and then sized and laid out inside their container. The component creation order is as follows:
The following example shows the major events that are dispatched during a component’s creation life cycle:
The creation order is different for containers and components because containers can be the parent of other components or containers. Components within the containers must also go through the creation order. If a container is the parent of another container, the inner container’s children must also go through the creation order.
Page 99
Building an d Deploying Adobe Flex 3 Applications
initialize
creationComplete
updateComplete
preinitialize
preinitialize
initialize
childAdd
creationComplete
updateComplete
Container
Component
The following example shows the major events that are dispatched during a container’s creation life cycle:
93ADOBE FLEX 3
After all components are created and drawn, the Application object dispatches an
applicationComplete event.
This is the last event dispatched during an application startup.
The creation order of multiview containers (navigators) is different from standard containers. By default, all top­level views of the navigator are instantiated. However, Flex creates only the children of the initially visible view. When the user navigates to the other views of the navigator, Flex creates those views’ children. For more infor­mation on the deferred creation of children of multiview containers, see “Using deferred creation” on page 94.
For a detailed description of the component creation life cycle, see “About creating advanced components” on
page 129 in Creating and Extending Adobe Flex 3 Components.
Page 100
CHAPTER 5
94

Using deferred creation

By default, containers create only the controls that initially appear to the user. Flex creates the container’s other descendants if the user navigates to them. Containers with a single view, such as Box, Form, and Grid containers, create all of their descendants during the container’s instantiation because these containers display all of their descendants immediately.
Containers with multiple views, called navigator containers, only create and display the descendants that are visible at any given time. These containers are the ViewStack, Accordion, and Tab N av ig at or containers.
When navigator containers are created, they do not immediately create all of their descendants, but only those descendants that are initially visible. Flex defers the creation of descendants that are not initially visible until the user navigates to a view that contains them.
The result of th is deferred creatio n is that an MX ML application with navigat or cont ainer s load s more quic kly, but the user experiences brief pauses when he or she moves from one view to another when interacting with the appli­cation.
You can instruct each container to create their children or defer the creation of their children at application startup by using the container’s loads. For more information, see “About the creationPolicy property” on page 94.
You can also create individual components whose instantiation is deferred by using the
createComponentsFromDescriptors() method. For more information, see “Creating deferred components”
on page 98.
creationPolicy property. This can improve the user experience after the application

About the creationPolicy property

To defer the creation of any comp onent, container, or child of a cont ainer, you use the creationPolicy property. Ever y container has a descendants when the container is created. You can change the policy of a container using MXML or ActionScript.
The valid values for the settings depends on whether the container is a navigator container (multiple-view container) or a single-view container. For information on the meaning of these values see “Single-view containers” on page 95 and “Multiple-
view containers” on page 95.
The
creationPolicy property is not inheritable. This means that if you set the value of the creationPolicy
property to
creationPolicy property, unless otherwise set. They do not inherit the value of none for their creationPolicy.
none on an outer container, all containers within that container have the default value of the
Also, if you have two containers at the same level (of the same type) and you set the them, the other container has the default value of the
creationPolicy property that determines how the container decides whether to create its
creationPolicy property are auto, all, none, and queued. The meaning of these
creationPolicy of one of
creationPolicy property unless you explicitly set it.
Loading...