Choosing the Right Mobile Development Platform – D2WC

I had a fantastic time in Kansas City last week at the Designer/Developer Workflow Conference. I ran a workshop  on jQuery Mobile and did a short talk on Choosing the Right Mobile Development Platform. I had a room full of great folks both times around!

I’ve just posted my slides from the talk on Speakerdeck. If you have any questions, please feel to ping me.

360|Flex – Choosing the Right Mobile Development Platform

Choosing the Right Mobile Platform

I had the pleasure of presenting “Choosing the Right Mobile Development Platform ” at this year’s 360|Flex conference. A full recap of the conference is in the works, but I wanted to get my slides up for those who wanted them. Here is what I spoke on,

As more and more projects are requiring mobile applications, developers are faced with a wide range of options. AIR for mobile? PhoneGap? Titanium’s Appcelerator? Sencha? Native? Which development environment makes sense? This session will explore the advantages and limitations of each of these environments from someone who has been in the mobile application development world for over 4 years. Get a clear picture of what these technologies can offer for your mobile development needs.

Understanding StageWebView and the viewport tag

My current solution for displaying dynamic interactive maps in my Android applications is to display a HTML-based Google Map within an instance of StageWebView. For the most part this has worked well, except for the long start up process. This often gives the appearance of the application being frozen. So, I sought a solution to try to improve the user experience.

The first step was to find a way to hide the StageWebView until it had finished its initialization and contacted the server. Since this component is of the ‘Stage’ type, this means that the normal display manipulation will not work. Instead, I created the viewport of the StageWebView offscreen. Now, I just need to know when it has contacted the server and the first page has been loaded. For this, you can listen for the Location Changed event. (Note, there appears to be a bug in AIR for Android 3.0, where this event is only fired upon the first URL that is accessed. This is important later).

Once the page has been loaded into our StageWebView, I reset the viewport to be on-screen. Since I have a loading spinner animating on the stage, this delay is now neatly masked.

Loading Indicator

Loading spinner

However, my screen still shows a white StageWebView. Then the map tiles are displayed, followed by the map controls. So how can I improve this portion of the process?

StageWebView initializing

The white StageWebView

In exploring the Google Map forums, I came across the notion of first serving a static Google Map, then waiting for the “tiles_loaded” event to be fired to swap the static map with the dynamic one. This was as simple as adding an <img> tag for the static map, and an event listener. In my web browser, this solution worked flawlessly.

Since there is a Location_Changing event that StageWebView is supposed to fire when the URL is changing, I thought I could tie into this by changing the page’s URL with an # attribute. But I then learned that this event does not currently properly fire on Android devices. I had planned to keep the StageWebView off-screen until the dynamic version of the map was ready before changing its viewport location.

Instead, I was forced to display the static map, then allow the loading of tiles and the map controls to occur visibly to the user. I soon ran into another problem. I had defined the width of the static map to be 480 pixels wide (I would have custom versions of the html page per device width), but once the html file was loaded into the StageWebView, I was able to scroll the image horizontally. What was going on!? Everything was working fine in my desktop browsers.

Map with scroll bars

Note the scroll bars

So, I began looking into the various attributes of the viewport meta tag, to see if there was something I could do to adjust the viewport. If you are not familiar with this tag, the Android documentation has a great reference on it. If you read through their documentation, you will learn that web pages on high-density devices (which is required to run AIR for Android) are automatically scaled by 150%. Eureka! Now I had confirmed why the static image became scrollable, now to find the solution. Reading further, there is another interesting attribute that can be set: target-densitydpi. To quote the documentation, “You can change the target screen density for your web page using the target-densitydpi viewport property.” This property has five values; device-dpi, high-dpi, medium-dpi, low-dpi, or a value. The one of interest for us is the device-dpi. If the target-densitydpi is set to device-dpi, the page will use the device’s native dpi as the target dpi and default scaling never occurs. And with this one addition to our viewport tag, our html file will now renders correctly on-device. Here is a sample apk and the source files.

Farewell Google Maps API for Flash

Well, the Google Maps API for Flash has been officially deprecated as of September 2, 2011. Bummer. I had hoped for an update to deal with better touch support and start up times. Although there are some alternatives out there (ESRI and Mapquest), so you still have solutions. FYI: Yahoo also recently discontinued their mapping solution for ActionScript as well.

I guess for desktop solutions, I will be mixing in HTML elements into my apps. For mobile, I will still use the StageWebView solution(until we get a Native Extension that will access the device’s native map solution). Update: Lee Brimelow from Adobe just posted a video demonstrating a Mapping Native Extension.