Wednesday, 28 September 2011

Android for the Java Developer - part 2

In part 1, there was a brief introduction to developing on Android from a Java programmer's perspective, with some of the similarities and differences highlighted.

The purpose of this article is look at some of these differences in more detail. For a pre-existing Java app, these are effectively the parts of an app that would require Android-specific development rather than simply re-using Java code. As a Java developer myself, they are also the differences I first noticed when I started to develop with Android.

When comparing the Java and Android development process, it's worth remembering that the two languages are there to address requirements. A client-side Java app would usually have been written for a desktop computer with a large screen, mouse and keyboard. In contrast, the Android app is likely to be running on a smaller device with touch screen and (possibly) no keyboard. In addition, the Android device may have other features you may want to make use of such as the GPS for location information, or the accelerometer.
That said, now let us look at some common tasks and consider how to approach them in Android...

User Interface Layouts

Most commonly, writing Java user interfaces meant using the java.awt or javax.swing packages. Due to a lack of good-quality UI building tools, this may have meant some painful manual coding. Anyone who has wrestled with the finer points of GridBagLayouts and the like knows what I mean. The good news is that Android makes UI design a lot easier by defining an XML-based layout language. Here is a fairly readable example of an XML fragment that produces a component with two buttons, labelled "Start" and "Exit":
<LinearLayout android:layout_width="fill_parent" android:layout_height="fill_parent" android:padding="5dp" android:orientation="vertical" <Button android:id="@+id/button_start" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Start" android:textSize="16dp" android:drawableLeft="@drawable/icon_start"/> <Button android:id="@+id/button_exit" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Exit" android:textSize="16dp" android:drawableLeft="@drawable/icon_exit"/> </LinearLayout>
Essentially your Android app should contain an XML layout file like this for each screen, which simply needs to be saved in the correct location (PROJECT_DIR/res/layout) in your project.

Handling Events

In Java, UI components and controls (such as buttons, menus, checkboxes, etc) have the ability for listeners to be assigned. The listener responds to any events from the component, such as a button press in this example:
Button startButton = new Button("Start"); startButton.addActionListener(new MyActionListener()); public class MyActionListener implements ActionListener { public void actionPerformed(ActionEvent evt) { //the button was pressed! } }
In Android, the model is almost exactly the same. Assuming the button in question has been defined in the XML layout file (see above), we can access the button in code and define a listener as follows:
Button startButton = findViewById(R.id.button_start); startButton.setOnClickListener(new MyOnClickListener()); public class MyOnClickListener implements OnClickListener { public void onClick(View view) { //the button was pressed! } }

Loading Graphics

Most applications will need to load image resources. In java, depending on how your project is structured, you may have something similar to this:
public class ImageHandler { private Image titleImage; public void loadImages() { URL url = ImageHandler.class.getResource("title.png"); if (url != null){ titleImage = Toolkit.getDefaultToolkit().getImage(url); } ... } }
In Android, some of the work is done for you. The image file simply needs to be dropped into a standard location in your project (PROJECT_DIR/res/drawable). The equivalent code would be:
public class ImageHandler { private Drawable titleImage; public void loadImages() { titleImage = resources.getDrawable(R.drawable.title); } ... }
The "R" class in Android is auto-generated by the build process. All your resources (images, sounds, layouts) can be accessed via this class.

On-screen Rendering

Sometimes you may need to draw shapes or images directly on screen using a Graphics context. This is typically the case with simple games. In a Java Applet/Application, you can use the Graphics or Graphics2D class do this:
public void paint(Graphics g) { //change the colour g.setColor(Color.BLUE); //draw some text g.drawString("Hello world", x1, y1); //draw a rectangle g.drawRect(x1, y1, wd, ht); //draw an image g.drawImage(titleImage, x1, y1, wd, ht, null); }
In Android, the approach is similar. There is a SurfaceHolder interface from which you can get a Canvas object to use for your drawing:
public void paint(Canvas canvas) { Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); //change the colour paint.setColor(Color.BLUE); //draw some text canvas.drawText("Hello world", x1, y1, paint); //draw a rectangle canvas.drawRect(x1, y1, x2, y2, paint); //draw an image titleImage.setBounds(x1, y1, x2, y2); titleImage.draw(canvas); }
Important differences to note: (1) In Android, it is necessary to create a Paint object - this will control details such as the colour, line thickness, etc of drawn objects. (2) In Android, methods such as drawRect use the coordinates of the rectangle's vertices (x1,y1) -> (x2,y2), rather than the width and height arguments as used by Java's drawRect.

Summary

We looked at some factors a developer needs to be aware of when developing on both Java and Android platforms, or when learning Android from a background in Java.

There are lots of other differences between the languages of course, but hopefully these represent a good starting point. Let me know if you think there should be more articles along these lines. The next article will be about using AdMob to generate income from in-app advertising.

No comments:

Post a Comment