Search code examples
javaandroidandroid-gradle-pluginannotation-processinggradle-plugin

Android annotation processing - generate different code for different build flavor


I'm building a library that requires some annotation processing to generate code. I now run into an issue that the release build doesn't need to have as much code as the debug build does (since this is a library for modifying configuration variants - primarily used for testing purposes). The following code illustrates the situations. Let's say I want to create a class ConfigManager from some annotated classes and properties. In debug builds, I need this much:

public class ConfigManager {
   public Class getConfigClass() {
      return abc.class;
   }
   public void method1() {
      doSomething1();
   }
   public void method2() {
      doSomething2();
   }
   public void method3() {
      doSomething3();
   }
}

While in release builds, I only need this much:

public class ConfigManager {
   public Class getConfigClass() {
      return abc.class;
   }
}

I have a feeling it may be possible by writing a Gradle plugin to check for build flavor at compile time and invoke a different processor/or somehow pass a parameter to a processor to generate different code. However this topic is pretty new to me so I'm not sure how to achieve this. A couple hours of googling also didnt help. So I'm wondering if anyone could give me a direction or example? Thanks


Solution

  • Pass an option (release=true/false) to your processor.

    From javac https://docs.oracle.com/javase/8/docs/technotes/tools/windows/javac.html

    -Akey[=value] Specifies options to pass to annotation processors. These options are not interpreted by javac directly, but are made available for use by individual processors. The key value should be one or more identifiers separated by a dot (.).

    In combination with Processor.html#getSupportedOptions https://docs.oracle.com/javase/8/docs/api/javax/annotation/processing/Processor.html#getSupportedOptions

    Returns the options recognized by this processor. An implementation of the processing tool must provide a way to pass processor-specific options distinctly from options passed to the tool itself, see getOptions.

    Implementation outline:

      public Set<String> getSupportedOptions() {
        Set<String> set = new HashSet<>();
        set.add("release");
        return set;
      }
    
      // -Arelease=true
      boolean isRelease(ProcessingEnvironment env) {
        return Boolean.parseBoolean(env.getOptions().get("release"));
      }
    

    See Pass options to JPAAnnotationProcessor from Gradle for how to pass options in a gradle build.