Tutorials, Videos

Tips for Flex mobile apps

28 Comments 16 December 2010

Tips for Flex mobile apps

After having developed several demo applications with Flex hero, I’d like to share with you some tips to improve the behavior of your native apps. Today, Flash Builder Burrito (still in beta) lets you develop native applications for Android devices and the BlackBerry PlayBook. The new <s:MobileApplication> tag and the new mobile components of Flex Hero dramatically improve the way you design an application. It’s already the most efficient framework for developing multi-screen applications, and it’s just a start, since Adobe will be adding more and more supported devices.

The video

Flex mobile application tips from michael chaize on Vimeo.

Same video on YouTube for my Chinese friends: http://www.youtube.com/watch?v=7LDyYl6ksOU

TIP #1: Kill your application

This is the number one misunderstanding with Android applications for Flash developers. When you exit your application (pushing the home button for instance), the application is still running in the background. You need to be aware of this default behavior and control it. This is a very powerful behavior inherited from Android, but it can sometimes kill the user experience on a smartphone. Let me give you an example. The Geolocation API introduced in AIR 2.5 returns your coordinates in real-time. On Android, it directly leverages the GPS API of the OS and we all know that that consumes a lot of resources. In this sample I just ask for my location using the Geolocation API and display the latitude in a text field. Don’t forget to add the Android permission “ACCESS_FINE_LOCATION” in the XML manifest.

On the first screen, you can see that my application is looking for my location as the GPS Android icon appears in the status bar. Then I click on the home button (screen 2). The GPS is still working in the background!!! If I look at the running services, the tip1quitHandler app is indeed still perfectly alive. It’s consuming my resources for nothing.

To control the behavior of your application, you must listen for the DEACTIVATE event on the native application. Just add these lines of code in your main MXML file:

<?xml version="1.0" encoding="utf-8"?>
<s:MobileApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
					 xmlns:s="library://ns.adobe.com/flex/spark"
					 firstView="views.tip1quitHandlerHome"
					 creationComplete="mobileapplication1_creationCompleteHandler(event)">
	<fx:Script>
		<![CDATA[
			import mx.events.FlexEvent;
 
			protected function mobileapplication1_creationCompleteHandler(event:FlexEvent):void
			{
 
				NativeApplication.nativeApplication.addEventListener(Event.DEACTIVATE, onDeactivateApp);
			}
 
			protected function onDeactivateApp(event:Event):void
			{
				NativeApplication.nativeApplication.exit();
			}
 
		]]>
	</fx:Script>
</s:MobileApplication>

In this case I just kill the application when the user goes back to the home screen. You can also choose to remove the event listener on the Geolocation, and activate it again when the Event.ACTIVATE is fired. It gives you more freedom and control than ever on Android.

TIP #2: Load your data before pushing a view

This is another classic mistake due to the new MobileApplication architecture. When you need to download some data from the Internet, don’t call the service in the view. If you do, you’ll launch a useless request every time you go back to it. Update the main application file to call your service and push the view on the result event. Remove the firstView parameter in the MobileApplication tag and call your service on the creationComplete event. When you receive a resultEvent, push the first view and pass the event.result object as an ArrayCollection.

protected function operation1():void
			{
				Operation1Result.token = speakersDevoxx.Operation1();
			}
 
			protected function mobileapplication1_creationCompleteHandler(event:FlexEvent):void
			{
				// TODO Auto-generated method stub
				operation1();
			}
 
			protected function Operation1Result_resultHandler(event:ResultEvent):void
			{
				// TODO Auto-generated method stub
				navigator.pushView(views.tip2devoxxHome,event.result as ArrayCollection);
			}

Check out the video to discover how I use the Data Wizard of Flash Builder 4 to build an app connected to the DEVOXX REST service in 5 minutes. Once your data is loaded, it’s persisted between the view. In my sample, I get the list of speakers and store it in an Array Collection. When I want to display the details about a speaker, I just push a new view passing the list.selectedItem object. Thanks to AIR 2.5, you can also choose to store the data locally in the SQLite database.

TIP #3: Display a custom label

Use the mobile item renderes to have the best performance while scrolling lists of data. Don’t forget that you can also use the labelFunction parameter in a List instead of the classic labelField. A typical use case is when you want to  display the full name of a user in the list. For example, if you only receive the first name and the last name from the service then use this simple trick.

<fx:Script>
		<![CDATA[
			public function myFullName(obj:Object):String
			{
				return(obj.lastName + " " + obj.firstName);
			}
 
			protected function list1_clickHandler(event:MouseEvent):void
			{
				// TODO Auto-generated method stub
				navigator.pushView(views.mySpeaker, list.selectedItem);
			}
 
		]]>
	</fx:Script>
	<s:List id="list" width="100%" height="100%" dataProvider="{data}" labelFunction="myFullName" click="list1_clickHandler(event)">
 
	</s:List>

TIP #4: Always declare a splash screen

Your AIR application will always take a second to start up. The Flex Hero framework added a tweak to the current Preloader class to display an image before the classic loading experience. Always declare a splash screen (just a static image) in your main MobileApplication tag to improve the user experience. It’s always better to welcome your users with an image rather than a black background. Several “ratio” parameters are available to control the display of the splash screen. You should consider the letterbox and the zoom ratio scale modes. Use the splashScreenImage and the splashScreenScaleMode parameters of your MobileApplication.

<s:MobileApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
					 xmlns:s="library://ns.adobe.com/flex/spark"
					 xmlns:speakersdevoxx="services.speakersdevoxx.*"
					  creationComplete="mobileapplication1_creationCompleteHandler(event)" title="Loading..."
					  splashScreenImage="@Embed('devoxxSplash.png')" splashScreenScaleMode="zoom">

TIP #5: Check the orientation of the screen

I’m a big fan of Flex 4 custom layouts. You can read my article about custom layouts here: http://www.riagora.com/2010/05/flex-4-and-custom-layouts/ By default, the mobile List component will use the VerticalLayout class. Depending on what you display, the VerticalLayout is not always the best choice. Depending on the orientation of your device (portrait or landscape), you may also want to change the layout associated with your list. When I display pictures, I prefer the TileLayout with a “rows” orientation but when I switch to the landscape mode, I prefer the TileLayout with a “columns” orientation. Here are two screenshots of the same application using two different layouts depending on the screen orientation.

On the left, you can admire the portrait mode, and on the right the landscape mode. To find out when the user rotates the screen, I listen for the ResizeEvent on the view… I’m not sure that it’s the best way to proceed… but it works :)

protected function checkOrientation():void{
				if(navigator.landscapeOrientation == true){
					currentState = "landScapeView";
				}else{
					currentState = "portrait";
				}
			}
 
			protected function onResizeView(event:ResizeEvent):void
			{
				checkOrientation();
			}

Then just declare the states of your application, and the layouts associated to your states:

<s:states>
		<s:State name="portrait"/>
		<s:State name="landScapeView"/>
	</s:states>
	<s:List width="100%"  height="100%" dataProvider="{myData}" itemRenderer="views.mySecondIR">
		<s:layout.portrait>
			<s:TileLayout orientation="rows"/>
		</s:layout.portrait>
		<s:layout.landScapeView>
			<s:TileLayout orientation="columns"/>
		</s:layout.landScapeView>
	</s:List>

TIP #6: Use custom layouts

I simply tried to use my custom coverflow layout and I was amazingly surprised by the good performances on my Android devices. Check out the video to see how it works.

TIP #7: Your tips

Now I need your tips ;) If you have found great tricks to improve Flex Mobile user experiences, please post a comment or a link to your blog post.

Post to Twitter

Your Comments

28 Comments so far

  1. Dhaya says:

    Thanks for sharing your tips ! What’s the name of the app you’re using to display and kill active tasks ?

  2. Christophe Keromen says:

    very useful, please keep posting on Mobile Development : pitfalls, optimization, debugging, multiscreen strategy and code organization…

  3. admin says:

    It’s by default on the samsung galaxy tab. Press the background three seconds, and then add this widget.

  4. Christophe Keromen says:

    regarding TIP #1: Kill your application

    1) you’ve got several free apps on the store (Advanced Task manager) that do the job

    2) is there a way to distinguish if I’m runnning on the real device (and so kill my app if desactivated) or testing it in AIR simulator and and don’t want to kill the app when desactivated as it prevents from debugging !

  5. Daniel says:

    Hi, very nice tips and article!

    But there’s a problem when using the DEACTIVATE event the way you did, if you open a browser, dialer, CameraRoll or even if you get a call while using the app the Event will be dispatched and it will kill your app. And some times you want to come back to it.

    I’d use listeners in the stage for the back and home keys and USER_IDLE with a timer.

    That’s my tip ;)

  6. admin says:

    Indeed. Nice tip. Thanks

  7. Erwan says:

    Awesome!
    I’m surprised to see that there is already so many good articles and documentation about Flex for Android, considering that this is still in beta!

  8. Christophe Keromen says:

    Regarding Tip#5: According to specs, if you would have used default states names (landscape and portrait), manually setting the state (currentState = “landScapeView”;) would have been useless, right?

  9. Mike says:

    Thanks for the great tips! I just started using Burrito and found them really helpful. I have a question about loading data before pushing a view. I got my app working with your tutorial. I was wondering if there is a way to load the data, push a view that displays a button. By clicking the the button push another view that would display a list with the content.

    Thanks in advance
    Mike

  10. Tadeusz says:

    Hi Michael,
    great tips

  11. Rafael Barradas says:

    Excuse me, Would somebody help me? When Can I find some examples or tutorials about Flex Mobile?

  12. Deepu says:

    Awesome,Fantastic work,It is reaily Helpful

  13. Landon says:

    Michael,

    Thanks for these tips. I have a question in regards to onDeactivateApp. I have found that this event is firing even when the lock screen comes up on a Droid 2, not just when the application is exited via the Home button or Back button. Is this the expected behavior?

  14. Gabriel says:

    is DatagramSocket will be supported on mobile any soon?
    Thanks
    Gabriel

  15. hi, Do you have the code for myTeam image gallery layout.

  16. If you use the DEACTIVATE event in a Flex 4.5.1 mobile app, and debug using the emulator, the event is fired on every view change and the app closes… but this does not happen when the app is running/debugging on the device (HTC Desire in my case)

  17. Joe says:

    Hi,
    I had a few issues doing some similar using your tips;
    1. navigator.landscapeOrientation, did not work. When I use it I get a compile error “Access of undefined property landscapeOrientation”

    2. When I tried to use the coverflow layout view, for some reason the layout gets messed up when I rotate it back. with the images slanted. But it works just fine using portrait and landscape states.

    I am still kind of new to flex so there might be something I am doing wrong. where can I get the source code for the one you demonstrated in your video, so I can compare or if you have the run into this question before it would be well appreciated.

  18. Raghu says:

    Hi,

    Is it possible to add effect (like fade effect) on splash screen?

  19. VivD says:

    Hi.. I’m trying out the coverflow layout in an app I’m working on. I’m having a few issues with implementing it. A look at your source code for the example in the video might help but I can’t seem to find the source code. Can you please point me to it?

  20. VivD says:

    I used the the code at http://www.rialvalue.com/blog/2010/03/30/flex4-coverflow-layout/
    and got the coverflow working. However, the that is missing is the ability to swipe on the image and move to the next. The code at that URL only switches to another image when you click on another image and not when you swipe on the center image.

  21. Bernardo says:

    how can i do that miy viewMenu always visible?

  22. Anish G Nair says:

    This blog helped me tackle some difficulties that I was facing.
    Thanx a lot. : )


Trackbacks/Pingbacks

  1. Flash Tips: Six Flex mobile application Tips | Adobe Flash Lite - December 17, 2010

    [...] CHAIZE has posted 6 Flex mobile application tips, Michaël shared us some tips to improve the behavior of your native apps. Flash Builder [...]

  2. Tips for Flex mobile apps via RIAgora « Geek Devigner - March 31, 2011

    [...] Code block [...]

  3. Divvi – collaborative photo sharing (part one) « Specialmoves Labs - July 29, 2011
  4. Flex 4.5 Mobile: Thoughts and Reading « Tales from a Trading Desk - August 11, 2011

    [...] Tips for Flex mobile apps [...]

Share your view

Post a comment

Who am I ?

I'm Michaël CHAIZE, Adobe Flash Platform Evangelist based in Paris. I'm a big fan of Rich Internet Applications and I promote the Flash Platform in the Enterprise world.
You can follow me on twitter: http://twitter.com/mchaize

Magazine

Follow us on Facebook

© 2014 RIAgora. Powered by WordPress.

Daily Edition Theme by WooThemes - Premium WordPress Themes