Berichten met label air
GraniteDS and AIR for mobile
Geplaatst door Walter Treur in Flex / AIR, iPhone/ iPad, java, mobility, technical op 5 september 2011
In this article I will briefly show how to resolve some obstacles I came across when I developed my first application with AIR for mobile and GraniteDS. The most noteworthy reason of using AIR to create mobile applications is of course the multi-platform deployment using a single codebase. Furthermore, with Granite you are able to disclose the services of an existing Java backend to a mobile platform without significant changes to the backend. This offers great potential for enterprises who are struggling with the fragmented mobile market and don’t want to completely rewrite their existing Java backend.
I will assume you have some familiarity with AIR for mobile and Granite. It’s mostly the same as for Flex but there are some things you have to take into account.
1. Get the right version of Granite
The latest version of Granite is 2.2.1 GA. However, in the most recent version of AIR and Flex Adobe made some changes in the API which breaks backwards compatibility for some features of Granite. Therefore this release of Granite won’t work using the newest SDK. Refer to this post on the Granite form for more info on how to make these changes yourself. If you don’t want be bothered with building Granite yourself just download this version of GraniteDS to get started immediately.
2. Connecting to the right server
A problem for AIR applications in general (both desktop and mobile) is setting the right server settings. It is quite simple when running within the browser: The server address is changed with a single reconfiguration of the swf-file and all clients are using the new address on a browser refresh. With AIR it is a bit different and you’re not always at liberty to ‘hardcode’ the service settings in the AIR distribution package.
Granite offers a method for dynamic server configuration using the server initializer component:
Tide.getInstance().addComponentWithFactory( "serviceInitializer", DefaultServiceInitializer, { contextRoot: '/my-app', serverName: “10.0.0.1”, serverPort: “8080” });
Note that once a connection is made, it is not possible to reconnect with another configuration, because the service initializer is only used once. You have to restart the application to enable the new connection settings or reset Tide’s RemoteObject. Unfortunately Tide’s API doesn’t support this reset. I came up with a small workaround which requires you to extend the EJB class with an extra reset method with the following body:
public class Ejb extends org.granite.tide.ejb.Ejb { /** * Reset the Tide Connection to allow new server settings */ public function resetConnection():void { if (_ro) { _ro.disconnect(); } _ro = null; } }
This method resets Tide’s RemoteObject so the next remote call will force a reinitialization using the current settings of serviceInitializer. Refer to Granite’s issue tracker or forum thread for more details.
3. Automatic logout
Applications running on mobile platforms are always susceptible to unpredictable interruptions. For example when a phone call or text is received. Mobile AIR applications provide a deactivate event which is dispatched when the application is halted somehow. The application I wrote was using Tide’s Identity class for user login. Therefore I added an event handler to automatically logout the user and push the LoginView on top of the navigator stack:
private function deactivateHandler(event:Event):void { if (identity.loggedIn) { identity.logout(); } navigator.popAll(); // Purge the navigator history to disable back button usage navigator.pushView(LoginView); }
4. Build, build, build!
This isn’t directly related to Granite or AIR for mobile. But since they can both be used for enterprise scale applications I thought I’d mention it shortly: Make sure you have a proper build script. Now, I’ve got an example from Chris Black which provides a good starting point. I’ve only added the metadata compiler options required for Tide and of course a reference to the Granite libraries and generated Actionscript classes.
<mxmlc ... > <!-- .... --> <!-- location of generated as classes with gas3 --> <source-path path-element="${gen.src.dir}" /> <compiler.library-path dir="${basedir}/libs" append="true"> <include name="granite-essentials.swc" /> <include name="granite.swc" /> </compiler.library-path> <keep-as3-metadata name="Bindable" /> <keep-as3-metadata name="ChangeEvent" /> <keep-as3-metadata name="Destroy" /> <keep-as3-metadata name="Id" /> <keep-as3-metadata name="In" /> <keep-as3-metadata name="Inject" /> <keep-as3-metadata name="Managed" /> <keep-as3-metadata name="ManagedEvent" /> <keep-as3-metadata name="Name" /> <keep-as3-metadata name="NonCommittingChangeEvent" /> <keep-as3-metadata name="Observer" /> <keep-as3-metadata name="Out" /> <keep-as3-metadata name="PostConstruct" /> <keep-as3-metadata name="Transient" /> <keep-as3-metadata name="Version" /> </mxmlc>
One plus one
I can imagine one must be thinking: ‘Everyone could have figured that out!’ And I totally agree, because that’s exactly what this article is about. With some experience with Flex, a developer can write a mobile application on top of a Java EE backend. It doesn’t take much to utilize an existing backend from a mobile platform. Since the latest release of AIR the performance for iOS and Android is pretty good and together with the Granite Enterprise Platform the barrier to emerge an enterprise application to a mobile platform has become much lower.
Introduction to AIR for mobile
Geplaatst door Walter Treur in Flex / AIR, android, mobility, technical op 6 november 2010
A couple of weeks ago, Adobe released a preview of the new Flash Builder and SDK. One of the new features is support for mobile devices using AIR. For now, only Android 2.2 is capable of running mobile AIR applications, but since Steve has changed the rules again, AIR on iOS is nearby, according to Adobe. Time to take a test drive with a tutorial.
Goal
We will create a simple RSS reader. Not a very exciting example, but already shows some nice features of AIR for mobile. I’ll assume you have experience with Flex or AIR, but I think you will manage with some level of programming experience. If not, feel free to leave a reply if you have any questions or take a look at the full source.
Setup

Download and install the preview release of Flash Builder called Burrito It provides a wizard to start an empty mobile application. By default the wizard creates two mxml files containing a MobileApplication and a View component.
The MobileApplication class is inherited from the Application class used for desktop AIR. The mobile version provides, among other things, an action bar and a navigator. Furthermore its firstView property points to the empty view component. The view component is a normal group, but optimized for mobile use as well.
Article list
Open the main view component (called <projectName>Home.mxml). Create a List component in the main view. Provide positioning constraints to let it occupy the whole screen.
<s:List left="0" top="0" bottom="0" right="0" />To retrieve the feed, create an HTTPService pointing to the RSS feed in the declaration section of the view. Add a resultHandler function to parse the feed-data. Parsing xml data is quite simple. You can just navigate to the DOM-tree as it were a normal ActionScript object. Use the data property of the view to store the articles locally. Using this property will provide some benefits with navigation, which will become clear in a bit.
<fx:Script> <![CDATA[ import mx.rpc.events.ResultEvent; protected function service_resultHandler(event:ResultEvent):void { data = event.result.rss.channel.item; } ]]> </fx:Script>
<fx:Declarations> <s:HTTPService id="service" url="http://lsd.luminis.nl/feed/" result="service_resultHandler(event)" /> </fx:Declarations>
Now there are only a couple of things left to do. Invoke the server and provide the list with the articles and instructions to show them.
Both are quite simple. The feeds are retrieved by invoking the send() method of the service. To automatically retrieve them, this method should be invoked when the view is created so we will use the creationComplete handler.
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" title="Home" creationComplete="service.send()">
Finally, bind the data property to the dataProvider of the list and set its labelField attribute to ‘title’.
<s:List dataProvider="{data}" labelField="title" left="0" top="0" bottom="0" right="0" />
Your view will probably look something like this.
<?xml version="1.0" encoding="utf-8"?> <s:View xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" title="Home" creationComplete="service.send()"> <fx:Script> <![CDATA[ import mx.rpc.events.ResultEvent; protected function service_resultHandler(event:ResultEvent):void { data = event.result.rss.channel.item; } ]]> </fx:Script> <fx:Declarations> <s:HTTPService id="service" url="http://lsd.luminis.nl/feed/" result="service_resultHandler(event)" /> </fx:Declarations> <s:List dataProvider="{data}" labelField="title" left="0" top="0" bottom="0" right="0" /> </s:View>
Emulator

Emulate hardware buttons
Now it is time to run a first test. Click the Run button and select ‘On Desktop’ as launch method in run configuration dialog. Also choose a device to simulate and run the application.
When the emulator is launched it shows a list of articles after a couple of seconds. Now you can select Rotate Right from the Device menu to display the landscape view. You will also notice the list is able to scroll up and down when dragging your mouse pointer (Which of course is the emulated equivalent of a one-finger swipe)
Article details
Next is to create a detailed view showing the full content of an article. Close the emulator and return to Flash Builder. In the views package, create a new component and call it DetailView. Bind the title attribute to data.title. Add a label as well and bind the text property to data.description. Don’t forget to specify the positioning constraints.
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" title="{data.title}"> <s:Label text="{data.description}" left="20" right="20" bottom="20" top="20" /> </s:View>
All view components provide a navigator object. We will use this in the change event handler of the article list. This event is fired when the user selects an article from the list. It looks as follows:
import spark.events.IndexChangeEvent; protected function articleList_changeHandler(event:IndexChangeEvent):void { navigator.pushView(DetailView, data[event.newIndex]); }
It simply instructs the navigator to create a new DetailView and push it on top of of the navigation stack. Furthermore the selected item from the article list is passed on to the data property of the DetailView.
Add the change handler and assign it to the change event of the article list:
<s:List dataProvider="{data}" labelField="title" change="articleList_changeHandler(event)" left="0" top="0" bottom="0" right="0" />

Article list inside the emulator
For performance optimization, AIR destroys the view when a user navigates away and recreates it when he returns. Only the contents of the data property is saved and passed into a recreated view of the same type. This is why we used it to store the articles. Otherwise the user has to wait for a reload when he returns to the main view.
When you launch the new version in the emulator, you will notice the application slides to the detail view when an article is selected. Click Back from the Device menu to simulate a click on the hardware back button.
Last but not least: action buttons
One thing our application is missing, is a button to go to the original webpage showing the full article. This button is placed inside the header of our detail view, next to the title.
To achieve this, add the button inside the actionContent of the detail view. Give the button an icon (I used one from the Tango project) and set the click handler to open the url of the article.
<s:actionContent> <s:Button click="{navigateToURL(new URLRequest(data.link))}" icon="@Embed('/assets/internet-web-browser.png')"/> </s:actionContent>
Of course you might want an additional button to return to the article list instead of using the ‘hardware button’. Place this button inside the navigationContent. This will place the back button at the upper left corner. The click event of this button will invoke the navigation.popView() method to remove the current view from the stack and return to the previous one.
<s:navigationContent> <s:Button click="navigator.popView()" icon="@Embed('/assets/go-previous.png')"/> </s:navigationContent>

Action and navigator buttons
If you launch the application you will notice the buttons are nicely aligned at the top of the screen.
What’s next?
The next step will be to package the application to an apk file so you could install it on an Android device. This is done by the Export Release build wizard inside the Project menu of Flash Builder. It includes the ability to sign your application to allow distribution through the Android Market.
Another nice feature which I will not discuss in detail is to add gesture based navigation. Take a look at this article from Adobe to find out more. The approach discussed should be working for mobile AIR applications as well.
Unfortunately the most interesting benefit of using AIR for mobile didn’t become clear with this tutorial. It would be nice to deploy our application on other mobile plastforms as well. However the cross compiler for iOS isn’t available yet and the same goes for AIR on Windows Phone, BlackBerry or Symbian. We will just have to wait when Adobe is ready so we can fully benefit from the “Write once, run anywhere” promise.
Developing a Flex AIR application
Geplaatst door admin in Uncategorized op 25 januari 2009
Project description
During the last few weeks, we’ve been working on setting up a sample application using Adobe Flex / ActionScript (working with Adobe Flex Builder 3).
Luminis had already developed a Web application for Nedap Healthcare, and we would like to know whether a desktop variant with an offline scenario would be possible. The web application displays items such as a worksheet, planning, news, weather and birthdays of colleagues.
The desktop application does not include all functionality of the Web application, but focuses on the worksheet. The existing functionality will be rebuilt in Flex and Air. The focus of our assignment was on modifying times in the worksheet and implementing an online / offline scenario.
User Interface
Web applications have set a new trend in interface design. The rules of interface design are no longer bound by the rules of the Operating System, and also no longer bound by the rules of the developer. The design for Web applications is usually defined by a designer, and implemented by the developer. For example the Gmail look and feel differs from a standard desktop application, but works in a familiar way. Buttons remain buttons, and input fields look like input fields, but there is the freedom to create a completely new interaction model and design.
The web application we were to base our desktop application on was designed by one of our team members which also did the interaction model. A specific design for a software application can help the customer to recognize the product and get a better feeling about the application. Don’t think of it as your corporate style embedded in the software, but also as user-friendly since it is targeted toward the end user.
The desktop application is a simple, familiar, user-friendly version of the Web application to be used by the target audience: women aged 40-50 years with little to no computer experience.

The interface is a direct derivative of the Web application and has the same look and feel.
The desktop application provides the same functionality as the web application, adding the possibility of changing times and the control of the application when it is offline.
Flex
Flex makes it easy and fast to build applications. This is especially due to the many standard components. Much can be modified in Flex, such as colors and properties such as shadows and corners. Also refer to the
Flex 3 Style Explorer
The same functionality of our Flex application could be built quickly if we would use standard Flex. The challenge was to make no concessions to our design. In this process in which we were responsible for design and implementation, it was occasionally hard to make a balance between adjusting the design or features in Flex to match original design.
The implementation
The most common approach building software appliances, is to build it with the standard components and skin it later on. This not only affects the design, but also does not involve the end user in the process.
The implementation chosen here is the same as implementing a design in HTML. From the existing design, slice the PSD and create a grid in Flex. Put the images into the grid and translate component design to Flex where necessary.
In Flex, the possibilities are extensive and there are minimal restrictions. Also covered are a lot of design possibilities like rounded corners, drop shadows and glows. This makes building your application very flexible. But also means you rebuild your original (Photoshop) design in Flex. So adjusting your original design could mean rebuilding your Flex implementation.
For example, when using the application, we noticed that there were indicators missing in the design. These were:
- Feedback to notify the user what the application was doing.
- An indication of whether the application was online or offline.
Not wanting to create a new, more complex design (adding items such as a status bar or an online/offline indicator [on/off light bulb]), we chose to show the online and offline situation turning the colors of the application to black and white, and displayed the status at the place where it is triggered on the button. The button is not useful when the application is busy.

Technologies
This should give an overview of the issues we ran into and how we solved them in the context of using the mentioned technologies to setup an AIR application. To get a bit of an overview of the possibilities of Flex / get familiar with the subject, a good first step would be to check out Tour de Flex. Since that application includes all (re)sources, it’s also very convenient as a reference / to get basic samples up-and-running quickly.
Now, moving on to the issues encountered and how we tackled them. Please note that the sample code below includes only non-standard import statements and is taken from an Adobe AIR application that uses AIR-only functionality!
XML
It took a while to get a bit of a feeling for creating and handling XML type objects. To illustrate, a number of relevant subtleties are incorporated in the following bit of code:
var i:int = 2;
var s:String = 'green';
// Convert a String value to an XML object to create the first element:
var e1:XML = XML("<element attr1='1'><label>first label</label>" +
"<color>blue</color></element>");
// Create the second XML element using the values of variables 'i' and 's':
var e2:XML =
<element attr1={i}>
<label>second label</label>
<color>{s}</color>
</element>;
// Now create the final XML object using the 2 elements that were created:
var x1:XML = <main>{e1}{e2}</main>;
// And query it for a specific attribute value ('attr1', be sure not to forget the '@'!)
// and element value (color) to determine the label value of a specific element:
var result:String = x1.element.(@attr1 == 2).(color == 'green').label;
// The value of the 'result' variable now is "second label". It would've been an empty
// string ("") in case no matching element was found.
HTTP POST
The application started out using only the HTTP GET method, which was easily achieved by using the HTTPService. However it was soon necessary to post data as well and getting the HTTPService to do this properly / finding some good examples (or even debuggin the (https) requests that were created properly) turned out to be a bit of a hassle. When we stumbled upon the URLRequest we got things up-and-running fairly easily:
import flash.net.*;
private function onPostComplete(event:Event):void {
}
private function doPost():void {
var dataToPost:XML = x1; // Posting the XML object from the previous example.
var urlLoader:URLLoader = new URLLoader();
// Define a handler in which actions can be defined for when the post is complete.
urlLoader.addEventListener(Event.COMPLETE, onPostComplete);
var urlToPostTo:String = "https://fillinyourhosthere.net/post.xml"
var urlRequest:URLRequest = new URLRequest(urlToPostTo);
urlRequest.data = dataToPost.toXMLString();
urlRequest.method = URLRequestMethod.POST;
urlLoader.load(urlRequest);
}
Online / Offline
Another requirement of the application was that it should be usable even if the target server went down or the client using the application is offline. As it turns out, this functionality is readily provided through using the URLMonitor:
// This code assumes a 'mx:WindowedApplication' with 'initialize="onWindowInitialized(event)"'.
import air.net.URLMonitor;
private var m_monitor:URLMonitor;
private function onWindowInitialized(e:Event):void {
var serviceURL:String = "https://fillinyourhosthere.net";
var serviceToMonitor:URLRequest = new URLRequest(serviceURL);
m_monitor = new URLMonitor(serviceToMonitor);
m_monitor.addEventListener(StatusEvent.STATUS, announceStatus);
m_monitor.start();
}
private function announceStatus(e:StatusEvent):void {
if (m_monitor.available) {
// Possibly update work that was done if previously offline.
} else {
// The application is (now) offline.
}
}
Updating DataProvider data
When using e.g. an array of data objects as a dataprovider for a TileList (or a DataGrid/AdvancedDataGrid) and changing (the value of) an item in the array, the view isn’t (always) updated immediately. If you want to see the changes immediately, you should use the invalidateList() method:
<mx:TileList
id="tl"
dataProvider="myDataProvider"
<!-- ...rest of the declaration... -->
// Do something that updates myDataProvider data.
tl.invalidateList();
Conclusion
There are still some things that could be improved on.
It would be preferable that the hours could be entered only through the use of keyboard, or mouse. Now you have to use both, and that makes it less intuitive. And corrupted/invalid data could be entered as the input fields are not masked.
Using Flex as a RIA developer kit can be fun, especially for designer who already know a bit of HTML/CSS and Javascript. Creating a skinned application in Flex is easy to do but still takes more time time than using the original components.
Patrick de Klein & Jaap Vriend
AIR brings RIA to the desktop
Geplaatst door Jeroen Bouvrie in technical op 11 juli 2007
When I was visiting the Adobe Live event in Amsterdam (May 2007) the session of Mike Downey about Apollo caught my attention. Adobe Integrated Runtime, code name Apollo, (see also AIR) is the runtime environment that brings rich internet applications to the desktop. This ‘desktop’ can exist on any platform where a runtime is available. At the moment of writing this blog entry, only Windows and Mac are supported but work is in progress to support linux as well as mobile phone platforms.
The idea is to use existing web technologies (HTML, Flash, Flex, Ajax) to create a RIA that runs in the AIR runtime and is able to use the AIR API, e.g. for caching purposes. This API is available through JavaScript or ActionScript. It is possible to manipulate entire HTML pages using DOM and subclassing the HTMLControl class. By doing so JavaScript actions can be manipulated or a submit can be intercepted. The AIR API offers functionality to detect if the application is online, to manipulate the window chrome (with transparency), clipboard, drag&drop, network functionality and local storage. JavaScript can call ActionScript and vice versa.
The deployable unit is a .AIR file that needs to be installed the first time. The API contains update functionality to get a latest version of an application.
When looking for cool AIR applications on the web it becomes clear that it is a challenge for developers to use cool graphics that make your rich internet application intuitive and really look good. From this perspective it does not matter if you use Flex 3 or e.g. Ajax. Flex 3 has some cool new animations (mx.effects package) but as a developer you better find a good interaction designer to cover that part. With AIR you can combine different RIA technologies and extend them with powerful desktop functionality. It is also interesting to see how fast we are able to build new applications based on the scripting environment(s) that AIR supports. More interesting AIR developer details with examples I will post in next entries in this blog.
Some applications start to show the real value of AIR; at this moment Adobe launched a contest to create the most unique Adobe AIR application. With actually some real cool prices; may we have your votes!
