Showing posts with label debugging. Show all posts
Showing posts with label debugging. Show all posts

Monday, 23 July 2012

Bug: AIR for Android, SharedObject and File


While working on a recent AIR for Android application, I found myself pulling my hair out over a strange bug. To speed up application development, I was persisting some of my application VOs using SharedObject, e.g:

var appSharedObject: SharedObject = SharedObject.getLocal( "appModel" );
appSharedObject.data[ "content" ] = vo;
appSharedObject.flush(  );

This had been working flawlessly for some time, and I had little reason to suspect it. The symptoms were particularly painful: after the application had finished with one View, persisted the data and attempted to move onto the next View, the application would unexpectedly close. There was no error, no crash and no stack trace.

Thankfully, my persistence layer had already been abstracted into a service, and I was able to implement an empty version and plug that in with little effort. With this in place, everything worked fine, so I was confident it had something to do with the SharedObject persistence. I needed to debug things further, but didn't want to spent hours rewriting the application.

Enter the [Transient] metadata. Adobe defines this metadata element as:

Identifies a property that should be omitted from data that is sent to the server when an ActionScript object is mapped to a Java object using [RemoteClass].

However, it can be used to provide hints to the SharedObject serialization system on which fields to ignore: marking any fields with [Transient] will see them ignored by SharedObject. By using this trick, I was able to use a binary search to very quickly identify which field was causing the problem. It turned out that a File instance containing a reference to a captured photo was causing a low-level crash with the AIR runtime, when it was serialized to a SharedObject; the same location stored in a String presents no problem (and, for that matter, files pointing to other locations present no problem).

Hopefully this saves someone else a heap of time!

Sunday, 10 July 2011

Remote Debugging in FlashBuilder

Disclaimer: There may be a better way to achieve this goal, but this trick has served me well for many years.

Occasionally the need to debug a Flex application that has not been launched from FlashBuilder arises: the application may be present in a UAT environment or it might need to be tested outside of the security-sandbox-free-zone.. In any case, you may not be able to launch it by simply clicking the "Debug" button on FlashBuilder's toolbar.

A workaround to this problem involves creating another debug profile for the application, by either selecting the "Run -> Debug Configurations..." menu item, or clicking the down arrow to the right of the "Debug" toolbar button and selecting "Debug Configurations..." In this screen, you should right-click on the configuration of the application of note, and select "Duplicate." The duplicated item will appear with a name like, "SampleApplication (1)." Select this debug profile in the tree, and then change the "URL or path to launch" configuration as follows:

  1. Untick the "Use default" checkbox.
  2. Enter "about:blank" as the URL.
Save your configuration by clicking the "Close" button, or launch it by clicking the "Debug" button.

The idea here is that when you launch this new debug profile, the browser associated with FlashBuilder will not open a page containing the Flex application, and thus a debug connection will not be established. However, FlashBuilder will still open up a debug listening service that will wait a short time before terminating. During this time, it is possible to manually load the application to be tested. As the application loads, it should connect to the debug session waiting within FlashBuilder, permitting the usual debug operation.