The Space For App Developers

Beyond Plain Old HTML Objects

Archive for December, 2010

Adobe Evangelist Blogroll released with seasonal theme

with 2 comments

Before I go to my family for Christmas Eve I just wanted to share with everyone that I released a new version of the Adobe Evangelists Blogroll application that comes with a nice seasonal theme :) Also I created this simplistic microsite for the AEB app so that you can easily navigate to Android Market or use QR Code to get it downloaded. So I wish you Happy Holidays and a Happy New Year!


Written by Piotr Walczyszyn

December 24th, 2010 at 3:36 pm

Posted in News,Releases

Tagged with

Paged list loaded from sqlite in Adobe AIR

with 2 comments

During my recent work on the Adobe Evangelists Blogroll application I wanted to implement a lazy-loaded/paginated List component with data coming from a local SQLite database. The reason for this was, of course, a memory usage consideration. Adobe Evangelists Blogroll is a mobile application so I didn’t want to load all available Post objects for each selected blog at once. I wanted it to be loaded dynamically as the user scrolls through the list. It turned out this wasn’t really difficult but there were few gotchas that I wanted to share:

  1. You have to implement your own IList component that throws ItemPendingError whenever the item requested with getItemAt function is not available yet. Unfortunately the Flex SDK doesn’t come with one built-in, but the good news is that you can use PagedArrayList class I created; its source code is available here :)
  2. Implement a createPendingItemFunction for the AsyncListView component. This function gets called when ItemPendingError is thrown and in our case serves two purposes. One is to trigger fetching the next page of rows from the database. It also returns a String with text that will be displayed temporarily in missing rows of the List. When that data gets fetched from the database those missing rows will be replaced with the loaded ones.
  3. One gotcha for the previous point is that if you are using SQLConnection in synchronous mode you will have to start fetching rows in the next frame after the call to the createPendingItemFunction function. That is why in my example I’m using callLater to execute the fetchRows function. This problem doesn’t arise with an asynchronous database connection.
  4. The last gotcha is most likely a bug in the Flex SDK. It occurs when the AsyncListView.list property is set before its list object is initialized and its length value is set. In that case invalidIndex error is thrown inside of LinearLayoutVector. The workaround I came up with is that right after setting the length property, PagedArrayList dispatches FlexEvent.INITIALIZE event; the application logic should handle it and programmatically set the AsyncListView.list property to the PagedArrayList instance. For reference I filed a bug in Flex SDK Jira.

Below you can find the source code that resolves the gotchas above. Also the whole Flash Builder project with paged list implementation is available here.

<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009" 
					   xmlns:s="library://ns.adobe.com/flex/spark" 
					   xmlns:mx="library://ns.adobe.com/flex/mx"
					   xmlns:helpers="com.riaspace.helpers.*"
					   preinitialize="windowedApplication_preinitializeHandler(event)"
					   creationComplete="windowedApplication_creationCompleteHandler(event)">
 
	<fx:Script>
		<![CDATA[
			import mx.collections.errors.ItemPendingError;
			import mx.events.FlexEvent;
 
			protected var conn:SQLConnection;
 
			protected const PAGE_SIZE:int = 50;
 
			protected function windowedApplication_preinitializeHandler(event:FlexEvent):void
			{
				// Creating inmemory database
				conn = new SQLConnection;
				conn.open();
 
				// Creating data_tab table
				var createStmt:SQLStatement = new SQLStatement;
				createStmt.sqlConnection = conn;
				createStmt.text = "CREATE TABLE data_tab (value_col TEXT)";
				createStmt.execute();
 
				// Inserting 1000 records to the table
				var insertStmt:SQLStatement = new SQLStatement;
				insertStmt.sqlConnection = conn;
				insertStmt.text = "INSERT INTO data_tab VALUES (?)";
 
				for (var i:int = 1; i <= 1000; i++)
				{
					insertStmt.clearParameters();
					insertStmt.parameters[0] = "value " + i;
					insertStmt.execute();
				}
			}
 
			protected function windowedApplication_creationCompleteHandler(event:FlexEvent):void
			{
				// STEP 1 - query rows count
				var stmt:SQLStatement = new SQLStatement;
				stmt.sqlConnection = conn;
				stmt.text = "SELECT count(*) as rowsCount FROM data_tab";
				stmt.execute();
 
				var result:SQLResult = stmt.getResult();
 
				// STEP 2 - set PagedArrayList.length equal queried rows count 
				pagedArrayList.length = result.data[0].rowsCount;
 
				// STEP 3 - fetch actual data starting from 0 offset (1st row)
				fetchRows(0);
			}
 
			protected function fetchRows(offset:int):void
			{
				// Fetch data rows with specified limit which is our requested page size
				// and offset passed as parameter
				var stmt:SQLStatement = new SQLStatement;
				stmt.sqlConnection = conn;
				stmt.text = "SELECT * FROM data_tab LIMIT :limit OFFSET :offset";
				stmt.parameters[":limit"] = PAGE_SIZE;
				stmt.parameters[":offset"] = offset;
				stmt.execute();
 
				var result:SQLResult = stmt.getResult();
				if (result && result.data)
				{
					for(var i:int = 0; i < result.data.length; i++)
					{
						// Setting return row at offset + i position
						pagedArrayList.setItemAt(result.data[i], offset + i);
					}
				}
			}
 
			private function createPendingItemFunctionHandler(index:int, ipe:ItemPendingError):Object
			{
				// In case synchronous database mode is used fetchRows function should be called
				// after return from this function. With asynchronous mode fetchRows function can
				// be called directly.
				callLater(fetchRows, [index]);
 
				// Returning a message to display
				return "List items are being fetched from database...";
			}
 
			protected function pagedArrayList_initializeHandler(event:FlexEvent):void
			{
				// NOTICE: this is a workaround for a Flex bug that causes invalidIndex error
				// in LinearLayoutVector. It all works well when asyncListView.list property
				// is set after pagedArrayList is initialized and its length property is set.
				asyncListView.list = pagedArrayList;
			}
 
		]]>
	</fx:Script>
 
	<fx:Declarations>
		<helpers:PagedArrayList id="pagedArrayList" initialize="pagedArrayList_initializeHandler(event)" />
	</fx:Declarations>
 
	<s:List width="100%" height="100%" labelField="value_col">
		<s:AsyncListView id="asyncListView" createPendingItemFunction="createPendingItemFunctionHandler" />
	</s:List>
 
</s:WindowedApplication>

Written by Piotr Walczyszyn

December 24th, 2010 at 11:21 am

Posted in Examples

Tagged with , ,

Adobe Evangelists Blogroll preview

with 10 comments

Today I’m officially announcing my new mobile application called Adobe Evangelists Blogroll. This is a simple RSS reader type of application that aggregates blog feeds from my fellow Adobe Evangelists. I’ve developed it with a preview release of Flex Hero SDK and it works on all Android devices that can handle AIR runtime. The app is available in Android Market if you look for “Adobe Evangelists Blogroll“.

What I’m also really excited about is that I managed to repackage it into a bar file and run it on BlackBerry PlayBook emulator without doing even single change to the codebase. In the video below you can see it in action running on different devices and also on PlayBook emulator.

As I already mentioned it was built with preview release of Flex SDK and also the app itself is in beta so it may have some quirks here and there. If you have any suggestions, comments or found some bugs you can contact me through this form.

Few screens of the application (running in landscape & portrait orientation and on playbook):

Written by Piotr Walczyszyn

December 20th, 2010 at 2:55 pm

Posted in News,Releases

Tagged with , , , ,

Flash StageVideo API performance overview

with 8 comments

As you may know, today Adobe released a beta version of upcoming Flash Player 10.2. This release brings few really cool features especially in the field of Flash video. In the recording below I demonstrate really incredible performance gains that you can have with new StageVideo API, which gives you full GPU acceleration of video content.

Written by Piotr Walczyszyn

December 1st, 2010 at 4:49 pm

Posted in Examples

Tagged with ,