This is an idea I had a couple of days ago, so I implemented a quick prototype: A JSXP-like code generator for android - project “resdroid”. The benefits of such a tool would be:

  • Easier ID handling: As long ad IDs are unique within an XML file, resdroid creates globally unique ids.
  • Don't say everything twice: From the XML file, resdroid creates a base class for activities
  • Simplify translations for common cases by generating the default translation file
  • Sanity-check translated strings
  • ...

The prototype just implements the first two features, and it only implements them for Buttons. This means it is not usable at all at the moment, but I think you get the idea how such a tool would work. The prototype can be found here on github: https://github.com/dtanzer/resdroid.

Usage

First create a directory called “resdroid” in your android eclipse project. To use resdroid you have to configure a builder in eclipse which runs the resdroid generator before building anything else. I use a shell file to run the generator, but an ant build would probably be better because it is platform independent.

resdroid.sh

#!/bin/sh
java -cp [path]/resdroid/target net.davidtanzer.resdroid.Generate $@

You can add the builder in the preferences of the eclipse android project. Make sure it is the first builder in the list. Configure the builder to refresh the project upon completion and to run after a clean and during manual builds and auto builds. You should also “Specify working set of relevant resources” - select the “resdroid” directory here.

Now you can create a layout within the “resdroid/layout” directory. The name of the file has to end in “.activity.xml” since resdroid can at the moment only generate activities.

resdroid/layout/test.activity.xml

<?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">
    <Button android:text="Button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/test_button"></Button>
    <TextView android:text="Foobar" android:layout_height="wrap_content" android:layout_width="fill_parent"></TextView>
</LinearLayout>

Note that the id of the button is only “test_button” here. This is OK because the ID does not have to be unique anymore - it will automatically be prefixed with a unique activity identifier.

Resdroid will automatically run when you save the file (if you have configured the builder correctly) and create the following two files:

res/layout/test_activity.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent">
    <Button android:text="Button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/test_test_button"></Button>
    <TextView android:text="Foobar" android:layout_height="wrap_content" android:layout_width="fill_parent"></TextView>
</LinearLayout>

generated/com/test/generated/TestActivityBase.java

package com.test.generated;
import android.app.Activity;
import android.os.Bundle;
import com.test.R;
import android.widget.Button;
public class TestActivityBase extends Activity {
	protected Button testbutton;
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.test_activity);
		testbutton = (Button) findViewById(R.id.test_test_button);
	}
}

The generated code is not formatted but otherwise it is the same as above. Now you only have to add “generated” as a source folder to your project, and then you can create the class “com.test.TestActivity” that extends the generated class. You only have to override onCreate and add a super call, then you can use the button.

Known issues

The graphical layout editor does not work when the XML file is not in “res/layout”. This should not be too hard to fix within the Android Developer Tools, but resdroid can not do anything about it.

Also, the scenario above is the only thing resdroid can do right now: It can create activities, but IDs can only be given to buttons, nothing else. Resdroid does not clean the “res” or the “generated” folder yet, which means that old XML files and classes might accumulate in these folders.

The source code is quite ugly in some places and the design/architecture is somewhat awkward because I had a different design in mind when I started. Also, I don’t use a template engine at the moment. I just wanted to quickly whack together a first prototype.

Feedback

I would really appreciate any feedback about resdroid. Is a tool like this desireable at all? Would you change anything? What other features would be cool? Please comment or send me an email.