Smarter ideas worth writing about.

Android Autowire Library

 

Writing an Android Activity comes with overhead.  All Android developers know this, and we get used to it.  But there are some ways to reduce the boilerplate code that have to be written for every activity, with minimal configuration and performance impact.

One particularly jarring example of Android boilerplate code is the findViewById() method.  Every time you want to access an Android view defined in your XML, you need to use this method, often with a typecast.  For large Activities with many views, this can add a lot of code that does nothing but pull variables out of the xml.

This library will help streamline this process into a more readable format using annotations and reflection.  By annotating a class variable for the View with the @AndriodView custom annotation, you enable the reflection code to pull the view out of the xml.  The variable name will be the view id, or alternatively, the view id can be specified in the annotation.  The annotation processing occurs in an overridden method of setContentView(int layoutResID) in the Activity's base class.

Here is an example Activity done the Android way:

public class MainActivity extends BaseActivity{

    private ImageView logo;

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

        logo = (ImageView) findViewById(R.id.logo);
    }
}

 

And here is the same Activity using the annotation method:

public class MainActivity extends BaseActivity{

    @AndroidView
    private ImageView logo;

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

 

With the BaseActivity:

public class BaseActivity extends Activity {

    @Override
    public void setContentView(int layoutResID) {
        super.setContentView(layoutResID);

        AndroidAutowire.autowire(this, BaseActivity.class);
    }
}

 

 

Configuration

This method of "autowiring" Android views would not be particularly useful if it required all kinds of setup and configuration in order to work.

Simply import the jar into the project classpath.  Make sure your Activities that want to use this extend from a base class that extends Activity.  Then add the override for setContentView. That's all there is to it.


Features

  • Supports Inheritance of Activities. You can have multiple Activities inheriting views, and every view will be picked up and wired in.
  • As it uses reflection, it will work with private variables.
  • Comes with several out of the box ways of specifying IDs allowing for flexibility in naming IDs and implanting the annotations.
  • Provides an optional required field in the annotation, so if an ID is not found, the variable will be skipped without an Exception being thrown.


Other Libraries

There are other libraries for Android that attempt to accomplish something similar. 

RoboGuice is a dependency injection library that can inject views in much the same way.  However, you must extend the Robo* classes, and there may be performance issues. (https://github.com/roboguice/roboguice/wiki)

Android Annotations can wire in views by annotation, but the approach they take is quite different.  Android Annotations requires you to use an extra compile step, creating generated Activity classes that must be referenced in the AndroidManifest.xml.  As this approach will create subclasses of your Activity, you cannot use this on private variables.  Additionally, there is much more configuration and initial setup. (https://github.com/excilys/androidannotations/wiki)

The real advantage to this library is ease of use.  There is minimal configuration in just about every IDE, and little overhead, allowing you to quickly start using these annotations in your new or existing project.  Instead of providing a full feature set, this library concentrates only on Android views, allowing it to fill the gap while still being lightweight.


Performance

While reflection code is known to be a bit inefficient on Android, this library is only looking at a small subset of the Activity fields, only the declared fields in each class extending from your base activity.  Performance is virtually the same as using findViewById(), even on some sizable activities with plenty of class variables.

The AndroidAutowire library is available at: https://github.com/CardinalNow/AndroidAutowire/tree/blog

Share:

About The Author

Senior Consultant
Jacob is an Enterprise Java consultant in Cardinal's Cincinnati office who is currently focused on mobile application development.