Android Development Explained by a JSF Developer

There are plenty of tutorials for Android App development out there. Picking the right one is already the first challenge. Though I am actually not an iOS developer, I believe that the quickest way to get started is to read articles which compare Android with iOS development, in such a way Clay Allsopp did. Having quite some experience with JavaServer Faces (JSF), I realized that there are both quite a lot of similarities and differences between the concepts of JSF and Android programming. Since it would have helped me when I started with my first mobile App, I wanted to share my findings in this post. Note that this is not a tutorial, but just an overview of concepts and technical terms one should know when planning to develop the first Android App.


Facelets vs. Layouts

In the Android world the views, in the context of the MVC pattern, are called layouts and will be implemented with XML. To get a little bit confused, the UI components are called views, e.g. TextView (h:outputText) or EditView (h:inputText). Android layouts use namespaces for attributes while Facelets need them for elements. Templating is not supported, but the possibility to include other XML files. HTML cannot be used, though Android basically supports HTML formatted output text. As a JSF developer, this is already almost everything you need to know to understand this sample layout:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 
	xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Enter Name" />

	<EditText
		android:id="@+id/nameInput"
		android:layout_width="wrap_content"
		android:layout_height="wrap_content"
		android:inputType="text|textNoSuggestions" >
		<requestFocus />
	</EditText>
	
	<Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="onSaveClick"
        android:text="Save" />

</LinearLayout>

Positioning

While you would use the panelGrid component, DIV tags and CSS to position your elements in your JSF application, Android provides layout managers. They influence the element’s width, height and position. You might know the idea of layout managers from programming GUIs with Swing. Ravi Tamada explained the major available layout managers: LinearLayout, RelativeLayout and TableLayout.

Managed Bean vs. Activity

Layouts are backed by so called Activities, which are custom Java classes and need to be registered in an XML file, the Manifest.xml. So far pretty similar to JSF. However, managed beans are (/should be) usually just models and can be reused at several views. But activities are specific to particular layout files and are strongly coupled with them. While Facelets files contain references to managed beans, Android will work vice versa. The activity class loads layout files and tries to find a component by its ID and then gets or sets values if required. Another big difference is the activity’s scope. Every activity has the same scope and will be only destroyed when the device is rotated, changes to power saving mode, the app is closed, an activity has not been used for a long time or when the user hits the device’s back button. Saving and restoring the screen’s state must be done manually, as it is described in the developer manual.
Let us see how a simple activity looks like:

public class MySampleActivity extends Activity {

	@Override
	public void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
		
		// load file: /res/layout/my_layout_file.xml
        setContentView(R.layout.my_layout_file);

	}
	
	@Override
	public void onSaveInstanceState(Bundle savedInstanceState) {
		// saving state instructions, if any...
		
		super.onSaveInstanceState(savedInstanceState);
	}
	
	@Override
	public void onRestoreInstanceState(Bundle savedInstanceState) {
		// restore state instructions, if any...
		
		super.onRestoreInstanceState(savedInstanceState);
	}
	
	/**
	 * Save Button Click (see XML above) handler
	 */
    public void onSaveClick(View v) {

    	// get field value
    	EditText nameField = (EditText) 
			this.findViewById(R.id.nameInput);
		String fieldValue = nameField.getText().toString();
    } 
}

Navigation Rules vs. Intents

With Android you can navigate to another screen (activity), open an URL or App, start a call or run a service. A simple navigation ID, as we use it in JSF, would not be sufficient. That is why there are “Intents”. You can create Intent instances which are nothing else but broadcasted messages and will be handled by the operating system. In your own App you can both broadcast and receive intents. It is also possible to send data along an intent, like you would send request parameters when accessing a dynamic web page. More about Intents can be found at the official API guides.
For simple tasks, the above description sounds more complicated than it actually is. Example for switching from one activity to another:

Intent intent = new Intent(this, TargetActivity.class);
startActivity(intent);

I18n and Resource Handling

Internationalization (i18n) and referencing resources works slightly differently. Instead of *.properties files you will have XML files and instead of EL expressions you can simply point to resource file names or identifiers with a particular syntax. Example of referencing an internationalized string:

<TextView
	android:layout_width="wrap_content"
	android:layout_height="wrap_content"
	android:text="@string/myTextIdentifier" />

Each resource type has a separate folder with sub folders for any variant of screen resolution, locale or device orientation. The operating system will chose the best fitting resource file during runtime. Read more about the available resource types and their variant options. So this concept is pretty similar to JSF’s library approach, but with more environmental influences.

Converters and Validators

Unfortunately, Android does not know JSF-like converters or validators which you simply would refer in the XML definition of a component. You need to implement all kind of validation by yourself and mark invalid input components manually. In exchange, there are much more specialized input fields so that converters are rarely required because the user cannot enter strings in an invalid format. You also have the possibility to implement and attach input filters in Java in order to make input fields even more specialized, e.g. a regular expression filter for formatting phone numbers. Still not very satisfying for me who is used to Java EE’s validation and JSF’s converters support, but we should keep in mind that a mobile app rarely contains tons of text input fields.

FacesMessages

Also the concept of adding message instances to the life cycle context which are automatically displayed if required, does not exist in Android. Any alert message must be implemented and controlled by yourself. There is also no standard component, such as h:messages, but you have several options. One common practice is to show a temporary pop-up message, a ‘Toast’.

AJAX vs. AsyncTask

Asynchronously reloading parts of a screen is extremely simple in JSF compared to Android. You would add the f:ajax tag to your component, specifying the target component ID and that’s it, right? Android requires to program everything in Java by implementing the AsyncTask interface. That usually means at least 50 lines of Java code per action. You can see some example code at my other blog post where I show how to access RESTful web services while displaying a progress dialog.

Still interested? Then get started with your first Android project!

Advertisements

Tags: ,

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: