Developing Android Applications Part 6: Services

Services are one of the major features of the Android application framework. They are a very simple concept in principle but it’s very easy to get confused about what a Service actually is. My recommendation is therefore to approach Services with a completely open mind – imagine they’re a completely new topic, and try to take in exactly what they are as well as what they can do.

What is a service?

A service can serve a number of purposes;

  • It can run a thread to keep something running in a loop / continuously
  • It can expose its functionality to other applications.
  • It can do other stuff, but just focus on the above for now M’kay!

The classic example you’ll see given everywhere, including in google’s introductory documentation, is a “music playing service”. You’ve already seen Activities, so you could logically conclude that a music playing application would have activities such as “choose a song” or “look at all of my albums”. When the application actually needs to play music though, your users will think it’s pretty useless if the tunes stop playing as soon as you stopped engaging in one of the aforementioned activities. You would expect the music to keep going if you started it regardless of what activity you were running. To take this one step further, you would also probably expect the music to keep playing if you returned to your home page! Therefore, activities can not perform the “playing music” role. In this case, a services would be used instead.

Services can do more than just play music though. Whilst that is a good example (and probably closer to what services will be more ‘generally’ used for) it skips over the other cool feature which is that a service can expose itself to other applications, allowing them to use its features. This functionality has more in common with a “web service”, and it’s this similarity that may very well be the inspiration behind the “service” naming convention. When you think of a web service, you think of an interface somebody has provided to you in order to easily accomplish a task which you would otherwise have had to program yourself (such as getting traffic reports or telling you the weather). Here, the exact same principle applies. You only need to use the tag in the application manifest to specify what it is your service needs access to and you’re away. Other uses you’re likely to see for services on actual Android devices include;

  • Services which check messages periodically
  • Services which check emails periodically
  • Live Wallpapers

Google themselves take the ingenious step of explaining what services are by describing what they aren’t. One can see how easy it would be to jump to the conclusion that a service is a separate process; it keeps running even when i’ve apparently “exited” my app, therefore it must have it’s own process right? Wrong! Your application itself is the process, and a service is nothing more than another component of your application. Here’s a demonstration to show you this principle in practice. Fire up an emulator (you can do this by running any example code you’ve made from one of the previous articles, or by running one of the samples that google provides). Incidentally, if you’re lucky enough to own an android phone, then you can do this exercise on the device itself too. Once the emulator has started up, get to the home page if you’re not already there (press the little house button on the emulator keypad) and touch the “launcher icon”, which is the little grid of squares that the robot dude is telling you to press in the following screenshot;

Once you’ve pressed that you should see a list of all applications installed on your real/virtual device. Fire up the “browser” application by clicking its icon. If you’re using the emulator, and unless you’ve messed with the defaults, your home page should be google (AS IT SHOULD BE!!!). Click the URL bar and browse to another site, in this case, I’ve gone to wikipedia;

Hit the home button again. Note that you return to the home page and your application appears to have closed. Press the “menu” button (again, from your emulators “physical keys” on the right). Incidentally, while we’re on the subject of those it’s worth pointing out that not all phones will have all keys, but all phones will have a means ‘to have done the same thing as pressing those keys’. Therefore, while there is a full set of a-z letters provided to you there, and indeed some phones do have a physical keyboard (HTC Desire Z, for example), you can’t rely on them being physical but you CAN rely on there being ‘another way to press them’ if they’re not. Anyway, moving on, after pressing “menu” select the “settings” option;

From the settings menu, select “Applications”;

and then finally select “Running Services”. You’l be presented with a screen like this;

Now, there are two services running on my device; one of them you’ll probably have too, but the other one (bouncing cat heads) is hopefully just exclusive to my device! Anyway, if you look at the screen you’ll see that there is a grey bar followed a list of things. The grey bar is the application (which in itself is a process), the stuff directly below the grey bar represents the services within that application. On the screen-shot there’s only one service running in each application, but you can have more than one. Notice the absence of the “browser” application though?

Now hit the “Home” physical key to return to the home page, then use the launcher icon to bring your browser back up. You’ll notice that the browser has returned to wikipedia (or whatever other website you decided to visit earlier on in the steps). The browser has remembered where you were, without using a service.

Hopefully this should be enough to convince you that services aren’t processes, applications are!

So I guess you’re wondering how long that application would keep running then? How long exactly would that browser remember that you were on the wikipedia page last time you used it? Well, that’s not really about services but I’ll answer it anyway: It’ll remain “remembered” as long as there is memory to do so. If memory starts running out, the “oldest remembered” app gets its state erased.

So what were the bouncing cat heads??!

Yeah, that other service that was running. Well, that’s actually the service example I’m going to be demonstrating next. It’s an example of a “live wallpaper” service, which are those funky moving wallpapers. Stay tuned if you want to know how to implement bouncing rotating cat heads on your android phone!

How to develop Pong for Android

Note: This guide was written a little while back, and it looks like there have been some changes since (specifically it looks like a setting in eclipse) see comments for details if you have any problems

So it turns out I’m going to be having an article published in this months’ print issue of the video-game industry magazine “Develop”. Quite how that happened I have no idea, but I’m totally thrilled about it and so wanted to do something game-related in case any of that magazine’s readers decide to check out the blog afterwards. (EDIT: Unfortunately the article never materialized, I had to find this out by buying the magazine and then realizing that I wasn’t in it. haven’t heard a peep out of them either. nice!)

I do, however, need to make one thing really, really clear first of all…

I AM NOT A GAME DEVELOPER!

I don’t purport to be one, I don’t even particularly want to be one. I don’t really know the first thing about making a decent game engine, although that’s not to say I haven’t dabbled in the past. One thing that you should therefore bear in mind is that what follows is likely to be a textbook example of how not to code games. What it will do though, hopefully, is to demonstrate enough about the Android platform such that anyone who IS a game developer would be able to work through this example and figure out how to do it “the good way”.

I have also cut a lot of corners here in terms of general good programming practices. Within the example you’ll find tons of hard coded literals within methods. I have only done this here because I’m attempting to strip down the code to the very basics to help you see what’s going on.

My twin brother Stew, a game developer by trade, once told me that whenever he’s trying to get to grips with a new API the first thing he does is knock out a Bejeweled clone in all its recursive and particle-laden glory. Personally, I tend to go for pong 🙂

So here we go then: Let’s make Pong for the Android platform!

 


 

Start up a new Project

I went for the following options when starting up this project; Feel free to substitute in your own alternatives if you want, but bear in mind that if you do then you’ll need to alter the rest of the code to accommodate.

 


 

The basic architecture we’re going for

We are going to be aiming for only one Activity. This activity will be “playing pong”, and this will be the only activity that a user will be able to do with our application. Other potential activities could have been “looking at the high score table” or “selecting options from the menu”, but those won’t be implemented here. Moreover, we are actually not going to change the Activity at all from the one you’re given when you start the project, because all of the work is going to be done by a View.

We are going to create a new type of view; one which has a thread associated with it. The job of this view will be to start and stop the thread, and to listen for user interaction.

The thread will also be a new type of thread, one which has a game state associated with it. The role of this thread will be to run two methods over and over: update() and draw(), both of which will be methods within the aforementioned state. The thread will also create Canvas and Paint objects (which are used for drawing).
The game state object will be a set of methods and members defining what the current state of the game is.

 


 

Implementing the GameView

So as previously mentioned, there should be no need for us to change the default activity that you’re given when you create a new project, but just in case, open up the file and make sure that all it’s doing is defining the content view as being your layout.xml file. It should just look something like this;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }

We are actually going to be creating a new type of view called a GameView, and then just putting a reference to it in our layout xml, meaning that the above will be fine just as it is. Create a new java source file called “GameView.java” in your src directory, and add in the following code;

public class GameView extends SurfaceView  implements SurfaceHolder.Callback
 {
    private GameThread _thread;

    public GameView(Context context, AttributeSet attrs) {
        super(context, attrs);

    	//So we can listen for events...
        SurfaceHolder holder = getHolder();
        holder.addCallback(this);
        setFocusable(true); 

        //and instantiate the thread
        _thread = new GameThread(holder, context, new Handler());
    }  

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent msg) {
        return _thread.getGameState().keyPressed(keyCode, msg);
    }

    //Implemented as part of the SurfaceHolder.Callback interface
	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width,
			int height) {
		//Mandatory, just swallowing it for this example

	}

    //Implemented as part of the SurfaceHolder.Callback interface
	@Override
	public void surfaceCreated(SurfaceHolder holder) {
		_thread.start();
	}

    //Implemented as part of the SurfaceHolder.Callback interface
	@Override
	public void surfaceDestroyed(SurfaceHolder holder) {
        _thread.stop();
	}
}

This code will give you errors when you first paste it, because you have not yet implemented the “GameThread” object that exists here as a member. Ignore the errors for now and resist running until we’re done! Let’s just do a quick post-mortem of the above code. It’s a new type of View that extends the android “SurfaceView” object. This is a special kind of view that provides a dedicated drawing surface. As we are interested in hearing about any alterations and interactions pertaining to the view, we therefore also implement the “Callback” interface nested within the SurfaceView class, which means we need the three methods “surfaceCreated”, “surfaceChanged” and “surfaceDestroyed”. I start and stop the thread within the create/destroy methods, and just swallow the “changed” one.

You will also notice the “onKeyDown” method, which is overridden from a method that exists in every View (it’s in the View object, in fact). We don’t want our view to be making changes directly to our game state, the game state should change itself based on the user interaction. Therefore, all we do if a key is pressed is pass the information down to the game state (which, again, you haven’t implemented yet).

The final thing to do is to head into your layout.xml file and add in a reference to your new view. Just replace whatever is there with the following code;

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.mikey.pong.GameView
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</FrameLayout>

Obviously changing the package name to whatever you called yours. The other thing it’s worth pointing out here is that your new View is totally encapsulated: It’s doing it’s own thing on its own thread and will be quite happy sitting alongside other types of view such as spinners and galleries. You could, for example, put in a TextView here to hold the current score and just define that here in your XML rather than pasting text to the screen inside your GameView class. Keeping views seperated, and ensuring that they each have their own job to do and that they stick to doing just that, is a big step towards tidy and modular code.

 


 

Implementing the GameThread

Create another java source file named “GameThread.java” and paste in the following code;

public class GameThread extends Thread {

/** Handle to the surface manager object we interact with */
private SurfaceHolder _surfaceHolder;
private Paint _paint;
private GameState _state;

public GameThread(SurfaceHolder surfaceHolder, Context context, Handler handler)
{
_surfaceHolder = surfaceHolder;
_paint = new Paint();
_state = new GameState();
}

@Override
public void run() {
while(true)
{
Canvas canvas = _surfaceHolder.lockCanvas();
_state.update();
_state.draw(canvas,_paint);
_surfaceHolder.unlockCanvasAndPost(canvas);
}
}

public GameState getGameState()
{
return _state;
}
}

This will just be the thread that runs over and over while the game is running, and extends the “Thread” object (we will override the “run” method from this parent). We also add three members, all of which need to be accessed from the “run” method of the thread. Then there’s the “run” method itself, a continuous loop that just runs the draw and update methods of the game state (which we haven’t implemented yet). Finally there is just a getter method to return the state. We used this in our GameView class, so that we could tell the game state that a key had been pressed.

 


 

Implementing the GameState

This is where I get my head bitten off by any game developers! The horrific basilisk that follows is my very naive implementation of the game “pong”. I’m not going to go in depth into each and every line here, because it should be pretty obvious what it all does. It’s just three methods: draw, update and keypressed. Draw and update each get called in turn by the thread, keypressed gets called whenever a key is pressed. Keypressed and update serve to alter the member variables accordingly, and draw uses these members to draw appropriate shapes.

Create a new Java source file called “GameState.java” and paste in the following code.

public class GameState {

//screen width and height
final int _screenWidth = 300;
final int _screenHeight = 420;

//The ball
final int _ballSize = 10;
int _ballX = 100; 	int _ballY = 100;
int _ballVelocityX = 3; 	int _ballVelocityY = 3;

//The bats
final int _batLength = 75;	final int _batHeight = 10;
int _topBatX = (_screenWidth/2) - (_batLength / 2);
final int _topBatY = 20;
int _bottomBatX = (_screenWidth/2) - (_batLength / 2);	
final int _bottomBatY = 400;
final int _batSpeed = 3;

public GameState()
{
}

//The update method
public void update() {

_ballX += _ballVelocityX;
_ballY += _ballVelocityY;

//DEATH!
if(_ballY > _screenHeight || _ballY < 0)     	
{_ballX = 100; 	_ballY = 100;}  	//Collisions with the sides

if(_ballX > _screenWidth || _ballX < 0)
     		_ballVelocityX *= -1; 	//Collisions with the bats     	

if(_ballX > _topBatX && _ballX < _topBatX+_batLength && _ballY < _topBatY)     	
                 _ballVelocityY *= -1;  //Collisions with the bats     	

if(_ballX > _bottomBatX && _ballX < _bottomBatX+_batLength 
                && _ballY > _bottomBatY)
                       _ballVelocityY *= -1;
}

public boolean keyPressed(int keyCode, KeyEvent msg)
{
if(keyCode == KeyEvent.KEYCODE_DPAD_LEFT) //left
{
_topBatX += _batSpeed; _bottomBatX -= _batSpeed;
}

if(keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) //right
{
_topBatX -= _batSpeed; _bottomBatX += _batSpeed;
}

return true;
}

//the draw method
public void draw(Canvas canvas, Paint paint) {

//Clear the screen
canvas.drawRGB(20, 20, 20);

//set the colour
paint.setARGB(200, 0, 200, 0);

//draw the ball
canvas.drawRect(new Rect(_ballX,_ballY,_ballX + _ballSize,_ballY + _ballSize),
                             paint);

//draw the bats
canvas.drawRect(new Rect(_topBatX, _topBatY, _topBatX + _batLength,
                                      _topBatY + _batHeight), paint); //top bat
canvas.drawRect(new Rect(_bottomBatX, _bottomBatY, _bottomBatX + _batLength, 
                                      _bottomBatY + _batHeight), paint); //bottom bat

}
}

the two objects used in the “draw” method, paint and canvas, both contain extensive methods with which to draw and paste things to the screen. I won’t go into all the details here, but check out the API’s for both if you want more information, they’re both in the Graphics package.


And that is it!

Okay: You should now have all the code you need in order to run this thing. If you have any more errors, make sure you’ve optimized your imports on each of the four source files (just open each one and press ctrl-shift-O to have Eclipse do this for you). Run the game and you should see a ball bouncing around and two bats, pushing the left and right buttons on the android emulator should move the bats.

So concludes the horrific foray of a non-game developer into the world of Android games development. This will very much be a one off for me, as I’m more interested in e-commerce and the web, but this has been fun anyway and I can think of worse ways to spend a Saturday morning! I don’t think I’ve ever been more in need of a bacon sarnie than I am now.

Cheers!

Optimizing imports

To all the people who have been messaging me regarding code nor working: If you are using Eclipse use the following keyboard shortcut;

ctrl - shift - O

to automatically add any missing import statements to the top of your source files. This has been the cause of every question I’ve had so far, really useful shortcut sorry for not mentioning it earlier.

Developing Android Applications Part 5: Activities

The Activity class within the Android platform is something you need to get completely to grips with before you proceed: In true Hitchhikers Guide fashion, allow me to relay to you what the The official javadoc provided with the android SDK has to say about the Activity class;

“An activity is a single, focused thing that the user can do. Almost all activities interact with the user, so the Activity class takes care of creating a window for you in which you can place your UI with setContentView(View). While activities are often presented to the user as full-screen windows, they can also be used in other ways: as floating windows (via a theme with windowIsFloating set) or embedded inside of another activity (using ActivityGroup).”

A single focussed thing huh? When I first started Android development this was a tough concept to get to grips with, before I realised that in all of the time I’d spent using OO techniques I’d forgotten the main reason we use it in the first place: Because it allows us to model real world entities within the scope of a development environment. Years of exposure to web development, where objects are sterilized into either in-memory representations of database entities or response/request attributes had almost blinded me to this. I was looking for a way to think of an Activity purely on the merits of the members and methods it implemented. This did not help!

So it was time to go a bit Zen… ponder on purely the concept for a second: “An Activity is a single focussed thing that a user can do”. Don’t try and dissect it into any kind of computer concept, just think of it as a real world concept. They could be looking at a map, filling out a form, playing a game or browsing a gallery: These are all activities. Your application should be designed around the idea that a user will engage in various activities while using it, and the SDK is helping you to separate these out.

Just as the javadoc says, activities will have a View associated with them, and this view can take up either all of the screen or only part of the screen. If you’re an asp.net web forms developer, think of activities as your “code behind” files. The only difference is that here, rather than you having to bastardize the DOM in order to achieve what is roughly semantically correct, you actually have a real, working semantic model for representing a user interaction. If you’re an MVC developer, these can also be thought of as your controllers. Although I’m trying to draw parallels here, please note that these are approximations and should not be taken as literal comparisons!

All activities, as well as having classes, must be registered within your application manifest (AndroidManifest.xml). You do this by simply adding the following code to the manifest, within the application tag;

<activity     android:name=".MyActivity"
android:label="@string/app_name">
</activity>

That is, assuming that you’ve got an accompanying “MyActivity” class and you’ve left the “app_name” node as per the default within your strings.xml file. If you’re using eclipse, opening the ApplicationManifest.xml file will probably default you to the UI version of the editor. Personally, I believe these sorts of contraption to be the work of the devil 🙂 To get rid of it, all you have to do is use the tabs at the bottom of the screen to select the AndroidManifest.xml tab. Then you’ll see the actual xml that makes up your manifest.

You’ve already seen that at least one Activity must be at the heart of every application, and you can even specify the name of this activity in the creation of a project. Game developers: Please don’t think of this as your “main” method (you can have something like that, but this isn’t it!). This concept of a “main activity” is more akin to the idea of a website “index” or “home” page. One of your activities must serve as this page (the first activity a user will engage in when they first start your application). You specify which activity this is using the Application manifest again, this time with a child node within the activity node itself;

<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER"
</intent-filter>

 


 

How can an activity “hand off” to another activity?

Okay: Start a new android project and replace your layout.xml file’s content with the following;

<?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"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="I'm right here!!!!!"
/>

<Button
android:id="@+id/theButton"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="COME ON!!! DO IT!!!"
android:onClick="buttonClicked" />
</LinearLayout>

If you run your application, you should see a screen like this;

Clicking the button will result in an application error. This is because we haven’t implemented the listener yet (something to actually handle the button click, even though we have already defined this in our XML UI).

We’ll do this now. Create a second activity (remembering that you also have to declare this in the application manifest). If you use the following for the actual class;

public class TheOtherOne extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TextView tv = new TextView(this);
tv.setText("It it BLEEEDS, WE CAN KILL ITTTTT!!!!");
setContentView(tv);
}
}

Then you’ll be needing this in your application manifest (because remember, we need to register all activities in there);

<activity android:name=".TheOtherOne"
android:label="@string/app_name">
</activity>

Okay: So now the last thing is to make the hand-off then! Go back to whatever your ‘index’ activity is and replace the contents of the oncreate method with the following;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

Button theButton = (Button) findViewById(R.id.theButton);

theButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent myIntent = new Intent(v.getContext(), TheOtherOne.class);
startActivityForResult(myIntent, 0);
}
});
}

And there you go. Clicking the button on the resulting application should result in the following being displayed;

And that’s basically how you get your user to navigate around the various activities that your application wants to engage them in. Later on in this series, we’ll come to the concept of an “Adapter”, and we will definitely do more on the “Intent” object (very, very important!) but for now the listener approach described above should be familiar enough to web developers (it’s an event listener guys!) to help you getting along with your own Android learning. If you want to do more reading in the meantime, both the adapter and intent are good starting points. If you don’t fancy either of those, look into the concept of a “service”, one of the cooler aspects of the Android platform and one that provides a major advantage over its rivals.

Android ViewGroups: LinearLayout

This ViewGroup has a lot in common with the Silverlight “Stack Panel” control (in fact, it’s almost identical in usage). You specify whether the LinearLayout should arrange its children vertically or horizontally by defining an “orientation” attribute (if unspecified, the default is “hotizontal”). As stated previously, the children of a ViewGroup can also be a ViewGroup, so you can nest LinearLayouts within LinearLayouts.

The official android tutorial on Linear Layouts is here. There would be no point in me going over it again because that guide is pretty thorough and it should be fairly obvious what is going on (although if you do have any questions about it then drop me a line).

What that tutorial won’t tell you, however, is how to achieve the exact same layout programatically. Here’s how;


Step 1

Start a new Android project (or, just open up the one you did the above linearlayout tutorial in)


Setp 2

Create a new file within the “res/values” folder called “colours.xml”. Add the following code to it;

<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="red">#aa0000</color>
<color name="green">#00aa00</color>
<color name="blue">#0000aa</color>
<color name="yellow">#aaaa00</color>
</resources>

We are specifying our hex codes in an XML resource file. In the real world you wouldn’t name them “red, green, yellow etc.”, you’d give them meaningful names similar to the way you would name classes in web design. This way, if we ever wanted to re-skin our UI we would just have to change this file and wouldn’t have to alter any source code. This equates to a greater separation of concerns and a subsequently more manageable application.


Step 3

Replace the contents of the activity source file’s “oncreate” method with the following;

public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.main);

LinearLayout root = new LinearLayout(this);
root.setOrientation(LinearLayout.VERTICAL);
root.setLayoutParams(new LayoutParams(
LinearLayout.LayoutParams.FILL_PARENT,
LinearLayout.LayoutParams.FILL_PARENT));

LinearLayout top = new LinearLayout(this);
top.setOrientation(LinearLayout.HORIZONTAL);
top.setLayoutParams(new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.FILL_PARENT,
LinearLayout.LayoutParams.FILL_PARENT,
1.0f));

LinearLayout bottom = new LinearLayout(this);
bottom.setOrientation(LinearLayout.VERTICAL);
bottom.setLayoutParams(new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.FILL_PARENT,
LinearLayout.LayoutParams.FILL_PARENT,
1.0f));

TextView top1 = new TextView(this);
top1.setText("red");
top1.setTextSize(15.0f);
top1.setBackgroundResource(R.color.red);
top1.setGravity(Gravity.CENTER_HORIZONTAL);
top1.setLayoutParams(new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.FILL_PARENT,
1.0f));

TextView top2 = new TextView(this);
top2.setText("green");
top2.setTextSize(15.0f);
top2.setBackgroundResource(R.color.green);
top2.setGravity(Gravity.CENTER_HORIZONTAL);
top2.setLayoutParams(new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.FILL_PARENT,
1.0f));

TextView top3 = new TextView(this);
top3.setText("blue");
top3.setTextSize(15.0f);
top3.setBackgroundResource(R.color.blue);
top3.setGravity(Gravity.CENTER_HORIZONTAL);
top3.setLayoutParams(new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.FILL_PARENT,
1.0f));

TextView top4 = new TextView(this);
top4.setText("yellow");
top4.setTextSize(15.0f);
top4.setBackgroundResource(R.color.yellow);
top4.setGravity(Gravity.CENTER_HORIZONTAL);
top4.setLayoutParams(new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.FILL_PARENT,
1.0f));

TextView bottom1 = new TextView(this);
bottom1.setText("row one");
bottom1.setTextSize(15.0f);
bottom1.setLayoutParams(new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.FILL_PARENT,
1.0f));

TextView bottom2 = new TextView(this);
bottom2.setText("row one");
bottom2.setTextSize(15.0f);
bottom2.setLayoutParams(new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.FILL_PARENT,
1.0f));

TextView bottom3 = new TextView(this);
bottom3.setText("row one");
bottom3.setTextSize(15.0f);
bottom3.setLayoutParams(new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.FILL_PARENT,
1.0f));

TextView bottom4 = new TextView(this);
bottom4.setText("row one");
bottom4.setTextSize(15.0f);
bottom4.setLayoutParams(new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.FILL_PARENT,
1.0f));

top.addView(top1);
top.addView(top2);
top.addView(top3);
top.addView(top4);

bottom.addView(bottom1);
bottom.addView(bottom2);
bottom.addView(bottom3);
bottom.addView(bottom4);

root.addView(top);
root.addView(bottom);

setContentView(root);
}

Run your application and hey presto, an exact replica of google’s own linearlayout tutorial!

The code should be fairly easy to follow if you’re used to OO programming. All I’ve done here is instantiate each View as an object that I want to include in my UI, set the appropriate features on each one and then at the end I tie them all together. It’ll be easier to read and work through once you’ve got the above pasted into Eclipse (I don’t have syntax highlighting on this blog unfortunately). Anyway, that’s the LinearLayout ViewGroup!

Developing Android Applications Part 4: Layouts

All layout elements are descended from the “View” object, and these form the basis of any Android UI. To get this lingo out of the way from the get-go then, there are three terms that you’ll need to know when designing the presentation layer of an Android application;

Widget: A term used to describe UI elements. Note that there is no “Widget” object, it’s the name of a package.
View: A “thing that gets plonked on the screen”. Buttons, spinners, textboxes etc. will all inherit from the View object.
ViewGroup: A special kind of View object (direct descendant) that can have other views nested inside it (like HTML!).

The other bit of lingo that will be used here is “Activity”. I will go into more detail on this in a later article, but for now just think of it as “Something the user can do”.

Firstly we’ll be looking at the ViewGroup object, which in the standard API contains six direct subclasses (with further subclasses beyond that). We will be looking at three of them in particular;

  • LinearLayout
  • RelativeLayout
  • TableLayout

There are a bunch of subclasses of each of those too. If you’re interested in seeing all of those, the API page is here. Subclasses include the “Gallery” widget, and the “DatePicker” widget. Basically, the sexy ones. For now, we’re going to focus on these base classes though.

We are going to focus on these ViewGroup objects for now, and come to other types of widget later on. ViewGroups possess the ability to have other Views “nested” within them. Although the term ‘nested’ is generally only used when referring to markup languages, I’m going to use that term throughout even though you can develop your UI programatically too (in which case they’d be “arrays of pointers within the object”, but we’re going with “nested” m’kay 🙂 ) .

These articles will go over the types of ViewGroup available, how you use them, and also some of the basic settings you can use for each of them. In keeping with the idea of making these articles friendly to those migrating to the platform from a web development background, I’ll try to reference each ViewGroup back to a web equivalent. I will also go over how to achieve layout both programmatically and in XML.


Two ways to build your layout

Well, I say two ways but you are actually free to use a mixture of both as well (these methods certainly aren’t mutually exclusive). The two methods are as follows;

Define your UI programatically: This is where you build up the views from within the Activity by instantiating objects and eventually passing them to theActivity’s setContentView method. This way, the UI can be built at runtime. This approach will be familiar to swing programmers.

Define your UI in XML: Where you use the android schema to define your layout in XML and then reference this from within the Activity. This way, the UI is separated out from the application logic (a very desirable trait in modern architectures) and you can change the UI without having to rebuild your application. This approach will be familiar to XHTML designers.

There is no right or wrong method: each of the above approaches has an appropriate usage. Some users (particularly swing programmers) will prefer the programmatic approach, but generally it makes more sense to use the XML method. When you see the amount of work required for each, you’ll see why.


LayoutParams

All ViewGroup objects implement a nested class that extends the “LayoutParams” class. This class specifies the various layout related properties of any ViewGroup such as width or height. You can specify these either programatically or as xml attributes. Each widget will extend this LayoutParams class to add on its own features, but some features are common to all Views (those in the LayoutParams base class).

The parameters “layout width” and “layout height” are two examples of this. These must always be specified in ViewGroups, so I just want to go over them a little before we get cracking. You can specify the following values;

"fill_parent" / "match_parent"

This value will cause the View to be as large as its parent view allows it to be. These two are actually the same command, but the syntax was changed to “match parent” in API level 8. Similar to, but not exactly like, setting a contained <div> to have a 100% width style.

"wrap_content"

This value will cause the View to be as large as the content view requires it to be. Similar to having a <div> in HTML with no height or width styles specified.

So those are mandatory, but otherwise these layout parameters generally come with default values that are used if none are specified.


Documentation

Each of the base ViewGroups will be covered in a separate article. The reason for this is because I am going to be demonstrating how to create layouts programmatically in a very verbose fashion, so the pages may become quite long. Before We get on to that though, let’s have a quick look at the documentation available to you. To most programmers, a new language generally isn’t a big problem to learn; The general principles of programming languages tend to hold fast and all you’re faced with is a new syntax to get used to. New APIs, however, are always the trickiest part about learning a new platform. Fortunately, the android API is incredibly well documented. It all starts here;

http://developer.android.com/reference/packages.html

That page details every single package included in the android SDK. These pages tell you what any object does, how to use it, and in the case of views it tells you the xml attributes you can add to a layout AND shows you the programmatic equivalent. Take the “TextView” object for example;

http://developer.android.com/reference/android/widget/TextView.html

Obviously we haven’t come on to any actual examples yet, but if you look at the guide it tells you everything you’d need to know to incorporate this control into either an XML layout or a programmatically generated layout. I never thought I’d say this, but if you ever find yourself stuck, consult that API before consulting search engines!


On to the ViewGroups!

I am going to cover each ViewGroup in the articles that follow this one. When I’ve done one, I’ll put a link to it here. When I’ve done them all, I’ll probably delete this paragraph, so don’t get too attached to it 😀

I may also move on to other items in the meantime, instead of just focussing on layouts. Each layout will therefore not constitute another “Part” of this series, but will be featured here none the less.

Android Beginner Top Tip – How to fix the ‘main.out.xml’ issue

Okay if you’re only just beginning Android development, and you’re developing in Eclipse, you will almost certainly run into the following issue at some point. You’ve done ‘something’ and now your project won’t run and you can’t fix it no matter what you do.

The symptoms

You run your application and a weird new file appears in your project explorer called “main.out.xml”.

The application doesn’t build, and on your “Problems” tab in eclipse you get one or more of the following messages;

Premature end of file.	main.out.xml	
Unparsed aapt error(s)! Check the console for output.	
Unknown	Android Packaging Problem

Your console has the following errors in it;

Error in an XML file: aborting build.
main.xml:0: error: Resource entry main is already defined.
main.out.xml:0: Originally defined here.
main.out.xml:1: error: Error parsing XML: no element found

The cause

You’ll get yourself into this state if you attempt to run your code while you’re editing an xml file which aapt uses to generate any source files.

The solution

If you find this page through googling, chances are you’ve been banging your head against the wall because now your project won’t run at all whatever you do. The mistake you made here was to run while the xml file was open. You should only hit that button when a java source file is open. This won’t help you much now though, as trying to run the project will present you with the following error in a dialog box;

Your project contains error(s). Please fix them before running your application

Remedy is very simple though.

  1. Delete the “main.out.xml” file that was created
  2. Select “Clean…” from the “Project” menu
  3. Open a java source file and run again

and the project will run! From now on, only “Run” from a java source code file. I have also found that this solves the “R can not be resolved” error. As a general rule then, if your plugin is getting confused work through the above steps.

Post Mortem

I don’t know *exactly* how aapt is building your “gen” files when you run, but I do know that it uses the xml files to do it, so my current best working theory as to the cause of this problem is that having the file open in the editor puts some kind of lock on the file that prevents the plugin from parsing it correctly. If anyone has any further insights into this problem I’d love to hear them.