Cupboard, Paralloid and Fluffy

Time to share some interesting and delightfully named Android frameworks that were presented at Droidcon 2013:

Cupboard: simple persistence for Android -  I've used Grails for web development which has an excellent ORM (object-relational-mapping) layer;  developing data access objects is quick, easy and fun. Developing data access with SQLite for Android is like time travelling back to Mediaeval times. Cupboard makes it more bearable and fun, and also helps with reinforcing some abstraction. 

Paralloid: Parallax framework - Simple framework for parallax scrolling backgrounds. No more need be said, check out the link if this is something you need.

Little-Fluffy-Location-Library - Battery-friendly background location updates for Android. Handy for widgets that require periodic updates in background, and for apps that need a  current location available to them on startup. Also works for apps that do something with location periodically, such as getting updates from a server.

Robospice is a modular android library that makes writing asynchronous long running tasks easy. It is specialized in network requests, supports caching and offers REST requests out-of-the box using extension modules.

With cute names such as Cupboard, Little Fluffy and Parallold, who can resist?  

Now, I think I will go and play with Drools, Grails and Bouncy Castle.. just imagine trying to promote this tech stack to a client :)

Android App - Game States

Different game states were necessary for my app to make the flow and persistence  between screens manageable. Any state change results in game data save, so it is not possible to cheat if for example a card battle is going badly and you want to quit and restart.. the game will automatically persist the battle in the background (not blocking the UI) and reload the exact state when the game is restarted. Of course the advantage of this is that you can quit whenever you like and be able continue from exactly where you were last time.

cardsflow.png

Saving and loading data between the states however is not completely trivial especially if you have to save large chunks that must later be read from disk. This was my initial design using caching (implemented through a singleton that can be shared across activitites). The background save is implemented using android ASyncTask, a transaction design is implemented to ensure that partial-corrupt data is not saved. 

StatesDesign.png

Android Saving and Loading XML Data

Android persistence can be user initied, automatically executed at intervals or more importantly activity initiated if the activity quits when in the background so that the player can resume from exactly where they left off next time they load the app.

There are different ways to do this but this post is about using XML serialization, more specifically on using the Simple XML framework which is fully compatible with Android. I'm a big fan of it as it's strong proponent for convention over configuration.

Lets start with a game app example; say the user starts a new game, the activity will need to read the game data from somewhere initially. Put the 'template' or default game data xml file in ./assets/props folder in the Android project (create the /props folder inside assets if its not there already). Creating a FileUtilites class for read/write generic functions might be useful - in the sample below you can see the loadProperties method which returns a reader. The context object is from the activity which is used to return the assets and the filename that is passed to this methods is "props/gamedata.xml", for example. 

	public static Reader loadProperties(String filename, Context context) {
		Resources resources = context.getResources();
		try {
			InputStream is = context.getAssets().open(filename);
			int size = is.available();
			// Read the entire asset into a local byte buffer.
			byte[] buffer = new byte[size];
			is.read(buffer);
			is.close();
			// Convert the buffer into a string.
			String text = new String(buffer);
			Reader reader = new StringReader(text);
			return reader;
		} catch (IOException e) {
			// Should never happen!
			throw new RuntimeException(e);
		}
	}

The loadProperties functions returns a reader for the XML file, and this is where Simple XML comes into play. We create a new serializer object (to use it just include the necessary Simple XML classes in your class), which can then convert the XML from the reader to a Java object that can be your game data. Keep in mind, the idea is that the data in your properties folder will never be changed by your application, it is there to initialise, your app will persist the actual modifiable data to a different place. 

	Serializer serializer = new Persister();
	try {
		reader = FileUtils.loadProperties("props/"+ mapPropertiesFilename, context);
		tree = serializer.read(RPGCards.class, reader, false);
		return tree;
	} catch (Exception e) {
		// Should never happen!
		throw new RuntimeException(e);
	}

The next step is to persist the application data to the data folder, i'm tempted to say cache but it's not that, think of it as your app specific storage that your app can write to. The code below is pretty much self explanatory. The save location is "/data/data/com.packagename/" ,the package name is your app package. 

//write data 
	Serializer serializer = new Persister();
	File result = new File("/data/data/com.packagename/", "gamesave.xml");
	try {
		serializer.write(map, result);
	} catch (Exception e1) {
		e1.printStackTrace();
	}

and to load it from the data folder, in a similar manner

//read data
	File file = new File("/data/data/com.packagename/", "gamesave.xml");
	if (file.exists() ) { 
		Log.d(TAG, "load propertieslocation for player saveg game data ");
		try {
			map = serializer.read(Map.class, file);
			return map;
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

You can get Simple XML here http://simple.sourceforge.net/ - highly recommended!

Andengine Android Framework

If you are considering developing rich media applications on Android  games, make sure to look at Andengine 2D Open GL framework. It wraps the low level stuff and provides an excellent api for creating animations, sprites, effects and almost anything you can shake a stick at, it even has compatibility with TMX tile maps (TMX is a widely used format for designing tiled maps).

I used this framework for Warlock's Bounty on a low spec Orange San Francisco phone,  and it's been working admirably.

http://www.andengine.org/

Dealing With Android Activity States

It is important to understand how Android activities work in the context of persisting game data across different states. For complex apps one might require more than one activity, and retaining state as well as catering for abrupt pauses or exits can be a bit confusing. It's a very important design decision on how your app might handle these cases in the context of data persistence and usability.

An activity has many states as displayed in the state diagram below, but almost all the cases can be catered for just by using onPause, onStart and onResume. onPause will always be called when pausing/quitting an application pressing the home button or due to taking a phone call. onStart will only be called when a new Activity instance is created. 

activity_lifecycleandr.png

Warlock's Bounty uses xml serialization for presistence; every time onPause() is called in the Activity, a write to a temporary xml is executed so that when the app is opened  subsequently, it will check via onStart() if this xml exists, if yes then it resumes it's state and deletes the temporary xml. As Warlock's Bounty is turn based, there's no need to implement onResume() because there's no need to start/pause any entities in the game itself. 

public void onPause(){ 
super.onPause();
serialiseToXml();
}

public void onStart(){
super.onStart();
File file = new File(PersistenceManager.saveTempGameFilename);
//we load it then, only if it exists
if (file.exists()) {
//load data
//delete data
}
}

Don't forget to think about how you want your application to behave when the user presses the back button? Do you want it to save its state and go to start menu where the user will be presented with say a continue button, or do you want it to just quit and not save the state? You will need to handle this back key event well by implementing onBackPressed() in your Activity. One caveat is that you will need to have Android ver 2.1 or above, otherwise  you need to do additonal coding.