Tips & Tricks

The Inspection Connection – Issue #3, Annotation Validation

Android developers will be familiar with the concept of resource IDs, which are unique integers generated by the Android Asset Packaging Tool (aapt) for accessing resources within your application through the static class, `R`. Resource IDs are assigned to all resources defined inside your project’s `/res` directory.

In the past, it was common to inadvertently pass one resource type into a parameter that expected another, since they are both integers. IntelliJ IDEA now offers improved support for detecting mismatched resource types, thanks to some resourceful developers on the Android Tools Team. Tor Norbye explains.

Not only is it possible to detect mismatched resource types in Android’s APIs, now you too can leverage resource type checking in your own libraries and APIs on Android 19+, with resource type annotations. Like type annotations in Java 8+, these annotations will help validate parameter values at compile time:

public void toast(@StringRes int stringId) {
  Toast.makeText(getApplicationContext(), 
                 getString(stringId), 
                 Toast.LENGTH_SHORT).show();
} 

public void prepareToast() { 
  toast(R.menu.main); //Expected resource of type string
}

This inspection will detect two forms of resource type mismatches. The first is when you pass one type of resource into a parameter that expects another type, like above. The second will notify you when you have passed a constant into a type that only accepts a specific set of values. Let us consider the following example:

static class Butler {
  @StringDef({
      TEA_SERVICE,
      ROOM_SERVICE,
      DINNER_SERVICE
  })
  public @interface ServiceName {}
  public static final String TEA_SERVICE = "tea";
  public static final String ROOM_SERVICE = "room";
  public static final String DINNER_SERVICE = "dinner";

  public void doService(@ServiceName String name) {
    Log.i("Server", "Serving " + name + "...");
  }

  public void serveCountry() {
    doService("military"); //Must be one of TEA_SERVICE, ROOM_SERVICE, DINNER_SERVICE
  }
}

IntelliJ IDEA will detect both of these cases with the inspection Constant and Resource Type Mismatches, enabled by default under Inspections|Android. In order to use support annotations on Android 19+, you can add the following dependency to the dependencies section of your `build.gradle` file.

compile 'com.android.support:support-annotations:19+'

In addition to Nullness Annotations available in Android, IntelliJ IDEA 14 now offers a brand new, fully automatic nullity inference inspection based on bytecode analysis, to help you identify sites that may cause NPEs. Together, these features will help you identify bugs much sooner and develop with pleasure!

image description