Requirements
User level
Intermediate
Required products
Flash Builder (Download trial)
Download
Is it possible to build an application that will work across different devices that have very different form factors, screen resolutions, and physical screen sizes? Let’s narrow that question a bit, and ask “Is it possible to build a great looking application across smartphones and tablets for Android, iOS, and BlackBerry Tablet OS?” In other words, a high quality multi-screen mobile application is what I want to build.
This is where the Caltrain Times application comes in (see Figure 1). What is Caltrain Times? The Caltrain Times application is a train schedule viewer for the Caltrain commuter rail system in California. Caltrain provides a commuter rail service along the San Francisco Peninsula, through the South Bay to San Jose and Gilroy.
 
Figure01
This article discusses how I developed the Caltrain Times application, a good looking multi-screen mobile application. I'll touch on the full development cycle, starting with design all the way up to releasing the application to the app stores. The article is meant to highlight my experience and not meant to be a "one way or the highway" type of discussion. Depending on your application you might have more freedom in the various steps I outline below (i.e. workflow, testing, development, and optimization). Although it may vary for each application, if you are new to mobile development the approaches below will give you a good context for developing multi-screen mobile applications.
 

 
Workflow

Since I am a developer, and lack the skills to make a good looking application, I engaged a design firm to create some comps for the Caltrain Times application. With the feedback from some key people I provided images and concepts around how the application should look, act, and function. The resulting outcome was the design firm provided a Photoshop psd file with the comp of Caltrain Times. The file I received was the size of a portrait non-retina display iPhone/iPod (320x480). This was a mistake on my part, I did not clarify that I needed a high resolution comp. You always want the highest resolution comp, as you can easily scale images smaller and keep your fidelity but scaling up is hard to keep image fidelity.
Note: Going for a retina display resolution of 960x640 or a larger tablet format of 1024x600 is the place to start. I also think starting with the smartphone form factor first is a good idea. It is easier to expand out to a larger tablet size versus shrinking the design.
Before going back to the design firm I actually tried something in Photoshop. I opened the file in Photoshop and then went to Image > Image Size… and changed the Resolution (in the Document Size group) to double the value, 72 to 144. Photoshop does a good job of scaling up the bitmaps and font sizes, but it does not work for Effects very well. Especially effects like Stroke, which I had to manually open up and change the size of the stroke effect on a few assets. Not ideal but it saved a trip back to the design firm and worked out nicely for what I needed.
The next step was to cut up all the parts and get a list of the fonts and their settings used throughout the comp. Personally I lack Photoshop skills and know how to use Fireworks better. With this in mind I would get the different Photoshop layers turned off and on for the various assets I needed, then clicked Save for Web & Devices and exported the full comp (with different layers on and off) as PNG-24 images. This gave me a lossless and full transparent image to open in Fireworks and cut up. In Fireworks I would save a source file that had the highest resolution of the particular asset I wanted to export. I then exported to the smallest sized file format (png8 vs png32 vs jpg) that kept the highest fidelity of the asset. The exported asset was saved into three different folders all with the same name. For example, I opened up the GPSSource.jpg in Fireworks, first exported to the folder /assets/dpi320, after changing the Fireworks image size by 75% exported it to /assets/dpi240, and then at 50% exported it to /assets/dpi160 (see Figure 2).
 
Figure 2. Folders setup in the Caltrain Times project.
Figure 2. Folders setup in the Caltrain Times project.
 
Any time I had to go back and change or create a new asset I would still export it to all three folders, saving the source file as the highest resolution format. This made it easy to put all the asset DPI (dots per inch) versions into code without going back to Fireworks a bunch of times. And I could test across the different screens making sure there were no quirks in a specific DPI version. This leads to the next part of my process: testing!
 

 
Testing

The Flash Builder 4.5.1 mobile project allows you to target different platforms. You can configure different launch configurations to target each platform. Launch configurations define how run or debug launches the project on both desktop and device. It also allows you to provide device templates when running on the desktop. The device templates can be edited for various device screen resolutions and DPI's. Right in the beginning of the project I created three launch configurations for the desktop to run as a 160, 240, and 320 DPI device template (see Figure 3).
 
Figure 3. Launch configurations for the Caltrain Times project in Flash Builder 4.5.1, including the 160, 240, and 320 device configurations.
Figure 3. Launch configurations for the Caltrain Times project in Flash Builder 4.5.1, including the 160, 240, and 320 device configurations.
 
I coded up the bare minimum code to flush out the basic application layout. Things like the background image, header title, station selectors, train schedule lists, and transitions between states where tested with desktop launch configurations across the three DPI sizes. I didn't hook up any real data at this point but did provide some stubbed data when I needed items in the lists. Next, using separate launch configurations, I tested on devices themselves starting with Android and iOS. If I wasn't testing performance I would use the Fast packaging method ( adt –target ipa-test-interpreter ) for device option with the Apple iOS target platform (see Figure 4).
 
Figure 4. Fast packaging method for Apple iOS device launch method.
Figure 4. Fast packaging method for Apple iOS device launch method.
 
While working out the small details of item renderer states and different layout tweaks that might cause performance issues I still focused on getting the UI interactivity right first. This meant I used MXML and binding more freely to get things working the way I wanted, even though it might have been against mobile best practices. Once I had it working and tested on the desktop and devices with good enough performance I left it, and went on to the next UX issue. Finally once I had all the UI interactivity working and the assets rendering properly across all the device DPI sizes I started the next phase: development.
 

 
Development

This is the phase where all the data, services, GPS features, twitter integration, and final instructions view came together. I wrote a special AIR application to convert the Caltrain's General Transit Feed Specification file into a sqlite database. From there I have a default sqlite database with each application that can be updated over the wire (or with an application update) at a later date. The update was as simple as copying over the small sqlite db file. Most of the features I was able to test on the desktop, making it easy to debug and make changes. But I would always test the features on the various devices to make sure they were complete and worked properly.
The GPS feature I had to test on a device, but was really easy to hook up on the AIR side across the devices. I used a basic haversine forumla to calculate the distance to a train station. This works nicely because all the Caltrain stations are relative close. I did test the distance algorithm with set lat/lon values before testing on the devices to isolated the distance logic and confirm it was working before passing it real GPS data.
I used a few techniques in Flex to address the different screen DPI issues as well as smartphone vs tablet sizes. I implemented custom classes to override certain values for specific smartphone vs tablet use cases, including the splash screen and runtime DPI provider. I made heavy use of MultiDPIBitmapSource for image assets (see Figure 5).
 
Figure 5. Example of using MultiDPIBitmapSource for the background image
Figure 5. Example of using MultiDPIBitmapSource for the background image
 
Between CSS media queries and setting values in the constructor or creationComplete event of the application components I ended up with three sets of values for the layout and sizing (see Figure 6).
 
Figure 6. Example media query across the different DPI settings
Figure 6. Example media query across the different DPI settings
 
It was almost like writing the application three times, but not quite that bad. When I first started doing the three sets of assets and sizing values it felt a little weird. If you have tried to code for the various devices and all the premutations of screen sizes or resolutions you agree coding for three variations is not bad at all. I found that thinking of Flex's prescribed 160, 240, and 320 DPI values as three sets of devices or three unique skin sizing made it easy to understand and choose which sized skin I wanted for a particular device. This way of looking at Flex's DPI management allowed me not to use the device's actual DPI but apply the right skin, through the customer runtime DPI provider class, for the look I wanted. For example the tablets fall into the 160 DPI range, but using the customer runtime DPI provider I overrode the value to apply the 240 DPI settings instead, thus giving the tablet app a larger look which fills in the larger screen sizes the way I wanted it to. With all this, seemingly, extra work for creating and sizing three versions of the application's assets and layout what did I gain? I gained the full control to make the application look specifically the way I wanted for each class of the device.
Now that I have all the data and business logic worked into the application it was time to spend quality time playing with the application on devices and starting optimizing for performance and the last minute interactivity tweaks.
 

 
Optimization

During this phase I started looking at the best practices for mobile Flex applications. The first place to optimize was to convert my MXML item renderers to ActionScript-based ones. This took some getting used to but was not as hard as I thought. You have to get in the mind set that you will have to handle all the creation, placement, and rendering of your assets. A lot of the binding and layout values in MXML have to be explicitly set somewhere in the ActionScript code. For example, I was placing a graphic in the middle of its parent at a width of 90%. This is easy in mxml with using something like <s:Image id="img" horizontalCenter="0" widht="90%" /> , but in ActionScript I had to set the width explicitly and center the x position.
 
overrideprotectedfunction layoutContents(unscaledWidth:Number, unscaledHeight:Number):void { super.layoutContents(unscaledWidth, unscaledHeight); img.width = unscaledWidth * 0.9; img.x = (unscaledWidth-img.width)/2; }
Everything you do in MXML can be done in ActionScript. The trick is figuring out what MXML is doing for you, and then figure out where and how to explicitly do it in your custom ActionScript counterpart. I repeated this process of converting MXML components and item renderers until the performance is what I wanted across the devices. What I ended up with was a mix of MXML views and ActionScript item renderers. Now with the application looking, acting, and performing well it was time to release the application to the various marketplaces.
 

 
Releasing the app

Flash Builder made creating the release versions of all the packages a breeze. On the project I went to Export > Release Build, and up came a dialogue box with all the target platforms. I walked through all the dialog boxes and set up the production certificates, provisioning files, permissions, and platform specific package content settings. Then just clicked Finish and let it run, and out came a release .apk, .bar, and .ipa version of my app.
Note: To submit to the Amazon App Store you need to change the Deployment > AIR download URL to the Amazon's specific url.
The fun part was getting all the icons, screenshots, and descriptions together to submit to the various marketplaces. I submitted the application to the Android Market, Amazon Appstore, Apple App Store, BlackBerry App World, and Nook Marketplace. They all required different sized screenshots and icon sizes. I ended up with 13 screenshots, 8 splash screens, and 14 icons. To get the platform specific splash screens I ran the application on the device and use the device's screenshot functionality and then copied it to my computer. If on-device screenshots didn't work, or for ease, I use Flash Builder to create many of the screenshots. To do this I just created new launch configurations (see Figure 3) with specific resolutions required by the marketplaces and used a desktop screenshot software to create the image.
I signed up for the various developer/vendor accounts (some I had down before hand) and submitted the new app forms. Then I had to wait for the application to be approved across the various approval processes. In the end everything got approved within a week without any hiccups, which was nice. You can check out the application on the various marketplaces here, and also check out the source code for the application from the samples link at the top.
 

 
Where to go from here

Definitely take a look at the mobile application development capabilities in Flash Builder 4.5.1. It made testing and building the mobile application for the different platforms and devices very easy. Here are some links to more info about things I talked about above: