Air versus native Android applications

This weekend was cloudy and it rained so I decided to give some more time to play with my android phone. Even since I got the phone some time ago I tried on several occasions to do some fun development on it but it never seemed quite fun as expected so beside some play with the sensors, gps and camera I did not do much. However this time I was decided to do a different kind of test. I had in mind a simple application and I wanted to try how nice it is to develop it using the java android libraries from google and the air libraries from adobe.

The application

It is quite a simple application. In the first screen a login window is presented, the info is used to authenticate with a remote server, the response is evaluated and if the login is successful the JSESSION cookie is passed to a new view which connects to a service which returns a list of tasks which are displayed in a list. The server part existed and returned XML streams as response.

Conclusions

I will start with the conclusions and then show some examples of code. Note that this is a very basic application I did from scratch. First the time. Developing the android app took me about 3h and most of the time I searched the web various examples, the google doc was not enough. For the Air app it took me about 1h30 45min from which I spent downloading and installing the air env in a Windows virtual machine since they are not supported on linux. Second the code. For me the shorter the code the better the program and in this case there is absolutely no comparison, I wrote 4-5 times more code in order to the same think in android both in terms of java versus as and android xml versus mxml. Writing the android part proved much more frustrating for me mainly because all the things seems not to have the meaning you would expect, all the names are wrong. Take for instance the name of the function to set the query parameters: “setEntity” and the name of the function to set the headers: “setParams”.

XML gui definition

Android

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:orientation="vertical" android:layout_width="fill_parent"
	android:layout_height="fill_parent">
	<TableLayout android:id="@+id/tableLayout1"
		android:layout_width="match_parent" android:layout_height="wrap_content">
		<TableRow android:id="@+id/tableRow1" android:layout_width="wrap_content"
			android:layout_height="wrap_content">
			<TextView android:layout_height="wrap_content" android:text="Diapason login"
				android:layout_width="wrap_content" android:textAppearance="?android:attr/textAppearanceLarge"
				android:id="@+id/textView2" android:layout_span="2"></TextView>
		</TableRow>
		<TableRow android:id="@+id/tableRow1" android:layout_width="wrap_content"
			android:layout_height="wrap_content">
			<TextView android:layout_height="wrap_content" android:text="Username"
				android:layout_width="wrap_content" android:textAppearance="?android:attr/textAppearanceLarge"
				android:id="@+id/textView2"></TextView>
			<EditText android:id="@+id/username" android:layout_weight="1">
				<requestFocus></requestFocus>
			</EditText>
		</TableRow>
		<TableRow android:id="@+id/tableRow2" android:layout_width="wrap_content"
			android:layout_height="wrap_content">
		<TextView android:layout_height="wrap_content" android:text="Password"
			android:layout_width="wrap_content" android:textAppearance="?android:attr/textAppearanceLarge"
			android:id="@+id/textView1"></TextView>
		<EditText android:id="@+id/password" android:layout_height="wrap_content"
			android:layout_width="match_parent" android:inputType="textPassword" android:layout_weight="1"></EditText>
		</TableRow>
		<TableRow android:id="@+id/tableRow3" android:layout_height="wrap_content" android:layout_width="wrap_content">
			<Button android:text="Login" android:layout_height="wrap_content" android:id="@+id/login" android:layout_width="wrap_content" android:layout_column="1"></Button>
		</TableRow>
	</TableLayout>
</LinearLayout>

Air (flex)

<?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="HomeView"
		xmlns:mx="library://ns.adobe.com/flex/mx">	
	<fx:Declarations>
		<s:HTTPService id="loginService" url="http://localhost:8080/tasks/tasks" method="POST" result="onLoginService(event)" resultFormat="e4x"/>
	</fx:Declarations>
 
	<s:VGroup width="100%" height="100%" horizontalAlign="center">
		<s:Label text="Diapason login"/>
		<s:Spacer height="10"/>
		<s:Label text="Username"/>
		<s:TextInput id="username"/>
		<s:Label text="Password"/>
		<s:TextInput id="password" displayAsPassword="true"/>
		<s:Button id="login" label="Login" click="onLogin(event)"/>
	</s:VGroup>
</s:View>

Can you compare these two? Which is more readable? As a side note I agree that I simplified the flex part a bit because I could not find a grid component (the equivalent of the flex 3 mx:grid)

Making a request

Android

HttpPost post = new HttpPost(DpsnDroidActivity.dpsnURL);
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("defaultLocale", "en_US"));
params.add(new BasicNameValuePair("locale", "--"));
params.add(new BasicNameValuePair("pass",((EditText)findViewById(R.id.password)).getText().toString()));
params.add(new BasicNameValuePair("user", ((EditText)findViewById(R.id.username)).getText().toString()));
params.add(new BasicNameValuePair("service", "login"));
post.setEntity(new UrlEncodedFormEntity(params));
 
HttpResponse response = httpClient.execute(post, httpContext);
InputStream contentResponse = response.getEntity().getContent();

Flex

var params:Object = {
	locale: '--',
	defaultLocale: 'en_US',
	user: username.text,
	pass: password.text,
	service: 'login'
};
loginService.send(params);

The loginService was already defined in the mxml part.

XML parsing

It’s a bit pointless to compare the amount of code required to parse XML in java and in flex using e4x.

Filling a list

Android

NodeList nodes = (NodeList) xpath.evaluate(expression, inputSource, XPathConstants.NODESET);
List<HashMap<String, String>> listData = new ArrayList<HashMap<String,String>>();
for(int n=0; n<nodes.getLength(); n++){
	Node node = nodes.item(n);
	HashMap<String, String> entry = new HashMap<String, String>();
	entry.put("name", node.getAttributes().getNamedItem("name").getNodeValue());
	entry.put("description", node.getAttributes().getNamedItem("description").getNodeValue());
	//Log.i(TAG, node.getAttributes().getNamedItem("id").getNodeValue());
	listData.add(entry);
}
SimpleAdapter tasksAdapter = new SimpleAdapter(this, listData, R.layout.listitem,
					new String[]{"name","description"}, new int[]{R.id.name, R.id.description});
ListView tasks = (ListView)findViewById(R.id.tasks);
tasks.setAdapter(tasksAdapter);
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" android:id="@+id/linearLayout1">
    <TextView android:layout_height="wrap_content" android:text="TextView" android:layout_width="wrap_content" android:textAppearance="?android:attr/textAppearanceMedium" android:id="@+id/name"></TextView>
    <TextView android:text="TextView" android:id="@+id/description" android:layout_width="wrap_content" android:layout_height="wrap_content"></TextView>
</LinearLayout>

Flex

<s:XMLListCollection id="tasksData" source="{tasksService.lastResult.task}"/>
...
<s:List id="tasks" dataProvider="{tasksData}" width="100%" height="100%">
<s:itemRenderer>
	<fx:Component>
		<s:ItemRenderer>
			<s:VGroup>
				<s:Label text="{data.@name}"/>
				<s:Label text="{data.@description}"/>
			</s:VGroup>
		</s:ItemRenderer>
	</fx:Component>
</s:itemRenderer>
</s:List>

Final conclusions

I’m not saying here that one way of developing applications is better than the other or even faster after you get used to them not to mention in terms of deployment, hardware access and so many other criteria related to mobile development. My observations are personal and somehow aesthetic and from an aesthetic point of view android code is a very ugly code.

3 Responses

  1. So, what brand and model did you say your Android phone was?

  2. HTC Desire

  3. Thanks, great piece of hardware.

Leave a Reply

*