Making Android development a little more like Microsoft development

All aboard the Android train!

By day, I mostly use Microsoft development tools, and have used them for YEARS. I’ve been experimenting with some Android development recently, and was annoyed by several missing handy tricks that Microsoft tools have done for years. So, I just coded one replacement.

Commonly, in Microsoft platforms, when you create a user interface element (from VB3 to WPF and Silverlight) and give it an ID/Name, that named element is readily available in code-behind, without any extra effort. Nice.

Android development, apparently, is lacking that feature. So, I created a simple pattern to make it convenient for me. Imagine the following UI element defined in an Android Layout:

<Button android:id="@+id/btnSend" android:layout_width="fill_parent"
     android:layout_alignParentBottom="true" 
    android:layout_height="wrap_content" android:text="@string/send_message" />

As you can see, the id of the Button is btnSend.

Normally, in the backing Java class if you wanted to access that UI element, you’d add code like this:

Button btn = (Button) findViewById(R.id.btnSend);

Simple, but annoying for commonly accessed UI elements (or Views).

I’m not the best Java coder by any means as I’ve not done it full time for more than 10 years and my knowledge of any recent Java innovations is zero. So, take this code with a pinch of skepticism.

private void autoWire() {
    Field[] privateFields = this.getClass().getDeclaredFields();
            
    for(Field f : privateFields){
        f.setAccessible(true);            
        ViewId viewId = f.getAnnotation(ViewId.class);
        if (viewId != null ){
            try {
                f.set(this, (Object)this.findViewById(viewId.Id()));
            } catch (IllegalArgumentException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}

Now, in the onCreate method that is typical of an Android Activity, I call the method above, autoWire.

This Java code looks at the current class for declarations like this:

@ViewId(Id=R.id.btnSend)
private Button btnSend;

It’s just an annotation (ViewId), followed by the Id of the control.

The annotation definition is:

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * @author WiredPrairie
 *
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface ViewId {
    int Id();
}

Using autoWire, btnSend is automatically set and ready to rock and roll.