SlideShare a Scribd company logo
1 of 67
Download to read offline
Annotation
Processing
Tim
About me
Tim / Jintin

Android / iOS developer

Senior Software Engineer 

@ Carousell

https://github.com/Jintin

https://medium.com/@Jintin
How to write
flawless code?
Don’t write ANY code
Do write LESS code
“Annotation Processing is a tool we
can use to help us generate code in
compile time by labeling Annotations
inside our source code.”
Pros & Cons
+ Less boilerplate code

+ No Runtime Error

- Block incremental build

- Kotlin 1.3.30+

- Gradle 4.7+
- Compile overhead
One more thing…
One more inch…
How does Annotation
Processing work?
How we use it
dependencies {

implementation 'com.google.dagger:dagger:2.x'

kapt ‘com.google.dagger:dagger-compiler:2.x'

}
kapt stands for 

Kotlin annotation processing tool
Module structure
Library module (optional)

Processor(compiler) module

Annotation module
Annotation
Annotation
Attributes

Targets

Retention
Attribute
@GET(“XXX_Value")

Observable getAPI();

@Component(modules = {

AModule.class,

BModule.class,

CModule.class})

public interface MyComponent {}
Attribute
@Target(METHOD)

@Retention(RUNTIME)

public @interface GET {

String value() default "";

}

@Retention(RUNTIME)

@Target(TYPE)

public @interface Component {

Class<?>[] modules() default {};

Class<?>[] dependencies() default {};

}
Attribute
Primitive types (int, long, etc.)

String

Classes (Foo::class)

Enums

Other annotations

Arrays of the types listed above.
Annotation
Attributes

Targets

Retention
Target
@Retention(RetentionPolicy.RUNTIME)

@Target(value={CONSTRUCTOR, FIELD,
LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER,
TYPE})

public @interface Deprecated {}
Annotation
Attributes

Targets

Retention
Retention
@Target(ElementType.METHOD)

@Retention(SOURCE)

public @interface Override {}

@Target({ METHOD, CONSTRUCTOR, FIELD })

@Retention(RUNTIME)

public @interface Inject {}
Retention
public enum RetentionPolicy {

/* only exist before compile finish. */
SOURCE,
/* recorded in the class file by the compiler but need not
be retained by the VM at run time. */
CLASS,
/* to be recorded in the class file and can be used at run
time, so they may be read reflectively. */
RUNTIME
}
Retention
public enum RetentionPolicy {

/* only exist before compile finish. */
SOURCE,
/* recorded in the class file by the compiler but need not
be retained by the VM at run time. */
CLASS,
/* to be recorded in the class file and can be used at run
time, so they may be read reflectively. */
RUNTIME
}
Retention
public enum RetentionPolicy {

/* only exist before compile finish. */
SOURCE,
/* recorded in the class file by the compiler but need not
be retained by the VM at run time. */
CLASS,
/* to be recorded in the class file and can be used at run
time, so they may be read reflectively. */
RUNTIME
}
Retention
public enum RetentionPolicy {

/* only exist before compile finish. */
SOURCE,
/* recorded in the class file by the compiler but need not
be retained by the VM at run time. */
CLASS,
/* to be recorded in the class file and can be used at run
time, so they may be read reflectively. */
RUNTIME
}
Processor module
Only used in compile phase.

Not include in final Jar/Apk.

Can contain several Processors.
Hook
AutoService Hook
@AutoService(Processor::class)

class AdapterProcessor : Processor()



dependencies {

implementation ‘com.google.auto.service:auto-service:1.X’

}
public interface Processor {

/** Initializes with the processing environment. */
void init(ProcessingEnvironment processingEnv);

/** Returns the target the annotation types to process. */
Set<String> getSupportedAnnotationTypes();

/** Processes a set of annotation on type elements. */
boolean process(Set<? extends TypeElement> set, 

RoundEnvironment roundEnv);

…
}
Processor
public interface Processor {

/** Initializes with the processing environment. */
void init(ProcessingEnvironment processingEnv);

/** Returns the target the annotation types to process. */
Set<String> getSupportedAnnotationTypes();

/** Processes a set of annotation on type elements. */
boolean process(Set<? extends TypeElement> set, 

RoundEnvironment roundEnv);

…
}
Processor
public interface Processor {

/** Initializes with the processing environment. */
void init(ProcessingEnvironment processingEnv);

/** Returns the target the annotation types to process. */
Set<String> getSupportedAnnotationTypes();

/** Processes a set of annotation on type elements. */
boolean process(Set<? extends TypeElement> set, 

RoundEnvironment roundEnv);

…
}
Processor
public interface Processor {

/** Initializes with the processing environment. */
void init(ProcessingEnvironment processingEnv);

/** Returns the target the annotation types to process. */
Set<String> getSupportedAnnotationTypes();

/** Processes a set of annotation on type elements. */
boolean process(Set<? extends TypeElement> set, 

RoundEnvironment roundEnv);

…
}
Processor
Element
Unit of code element.

- PackageElement: Package

- TypeElement: Class, Interface

- ExecutableElement: Method, Constructor
@Override

public boolean process(Set<? extends TypeElement> set, 

RoundEnvironment roundEnv) {

for (Element element : 

roundEnv.getElementsAnnotatedWith(MyAnnotation.class)) {

if (element.getKind() != ElementKind.INTERFACE) {

error("Only interface can be used with MyAnnotation", element);

return true;

}

TypeElement typeElement = (TypeElement) element;

typeElement.getInterfaces();

typeElement.getSuperclass();

typeElement.getSimpleName();

MyAnnotation anno = element.getAnnotation(MyAnnotation.class);

/** Custom logic to build the relation graph and generate the file*/
}

return true;

}
@Override

public boolean process(Set<? extends TypeElement> set, 

RoundEnvironment roundEnv) {

for (Element element : 

roundEnv.getElementsAnnotatedWith(MyAnnotation.class)) {

if (element.getKind() != ElementKind.INTERFACE) {

error("Only interface can be used with MyAnnotation", element);

return true;

}

TypeElement typeElement = (TypeElement) element;

typeElement.getInterfaces();

typeElement.getSuperclass();

typeElement.getSimpleName();

MyAnnotation anno = element.getAnnotation(MyAnnotation.class);

/** Custom logic to build the relation graph and generate the file*/
}

return true;

}
@Override

public boolean process(Set<? extends TypeElement> set, 

RoundEnvironment roundEnv) {

for (Element element : 

roundEnv.getElementsAnnotatedWith(MyAnnotation.class)) {

if (element.getKind() != ElementKind.INTERFACE) {

error("Only interface can be used with MyAnnotation", element);

return true;

}

TypeElement typeElement = (TypeElement) element;

typeElement.getInterfaces();

typeElement.getSuperclass();

typeElement.getSimpleName();

MyAnnotation anno = element.getAnnotation(MyAnnotation.class);

/** Custom logic to build the relation graph and generate the file*/
}

return true;

}
@Override

public boolean process(Set<? extends TypeElement> set, 

RoundEnvironment roundEnv) {

for (Element element : 

roundEnv.getElementsAnnotatedWith(MyAnnotation.class)) {

if (element.getKind() != ElementKind.INTERFACE) {

error("Only interface can be used with MyAnnotation", element);

return true;

}

TypeElement typeElement = (TypeElement) element;

typeElement.getInterfaces();

typeElement.getSuperclass();

typeElement.getSimpleName();

MyAnnotation anno = element.getAnnotation(MyAnnotation.class);

/** Custom logic to build the relation graph and generate the file*/
}

return true;

}
@Override

public boolean process(Set<? extends TypeElement> set, 

RoundEnvironment roundEnv) {

for (Element element : 

roundEnv.getElementsAnnotatedWith(MyAnnotation.class)) {

if (element.getKind() != ElementKind.INTERFACE) {

error("Only interface can be used with MyAnnotation", element);

return true;

}

TypeElement typeElement = (TypeElement) element;

typeElement.getInterfaces();

typeElement.getSuperclass();

typeElement.getSimpleName();

MyAnnotation anno = element.getAnnotation(MyAnnotation.class);

/** Custom logic to build the relation graph and generate the file*/
}

return true;

}
How to create file?
Filer
Get from ProcessingEnvironment

Generate file under build folder
Filer
@Override

public synchronized void init(ProcessingEnvironment env) {

super.init(env);

filer = env.getFiler();

}

@Override

public boolean process(Set<? extends TypeElement> set, 

RoundEnvironment roundEnv) {

…
filer.createSourceFile(“NewFile", element);

}
How to create code?
JavaPoet/KotlinPoet
Provide simple API to generate Java/Kotlin file

Both Square open source projects

Over 8000 stars in total
MethodSpec main = MethodSpec.methodBuilder("main")

.build();
JavaPoet
MethodSpec main = MethodSpec.methodBuilder("main")

.build();



void main() {

}
JavaPoet
MethodSpec main = MethodSpec.methodBuilder("main")

.addParameter(String[].class, "args")

.build();



void main(String[] args) {

}
JavaPoet
MethodSpec main = MethodSpec.methodBuilder("main")

.addParameter(String[].class, "args")

.addStatement("$T.out.println($S)", System.class, 

"Hello, JavaPoet!")

.build();



void main(String[] args) {

System.out.println("Hello, JavaPoet!");

}
JavaPoet
MethodSpec main = MethodSpec.methodBuilder("main")

.addParameter(String[].class, "args")

.addStatement("$T.out.println($S)", System.class, 

“Hello, JavaPoet!")

.addModifiers(Modifier.PUBLIC, Modifier.STATIC)

.build();



public static void main(String[] args) {

System.out.println("Hello, JavaPoet!");

}
JavaPoet
TypeSpec helloWorld = TypeSpec.classBuilder("HellowWorld")

.addMethod(MethodSpec.{…})

.addModifiers(Modifier.PUBLIC, Modifier.FINAL)

.build();

public final class HelloWorld {

public static void main(String[] args) {

System.out.println("Hello, JavaPoet!");

}

}
JavaPoet
Tips
Find the boilerplate of daily work, eg: findViewById,
dependency graph, deep link, etc.

Find the pattern and define each component.

Label each component with annotation.

Create processor to generate code and link each
component.
Example
Factory
public interface Animal {}

public class Cat implements Animal {}

public class Dog implements Animal {}

public final class AnimalFactory {

public static Animal createAnimal(String type) {

switch(type) {

case "cat": return new Cat();

case "dog": return new Dog();

}

throw new RuntimeException("not support type");

}

}
Factory
public interface Animal {}

public class Cat implements Animal {}

public class Dog implements Animal {}

public final class AnimalFactory {

public static Animal createAnimal(String type) {

switch(type) {

case "cat": return new Cat();

case "dog": return new Dog();

}

throw new RuntimeException("not support type");

}

}
Auto Generate?
@AutoFactory

public interface Animal {}



@AutoElement(AnimalTags.CAT)

public class Cat implements Animal {}

@AutoElement(AnimalTags.DOG)

public class Dog implements Animal {}

// https://github.com/Jintin/AutoFactory
Example 2
1 ViewHolder
public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

protected static final int TYPE_HOLDER1 = 1;

@Override

public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

switch (viewType) {

case TYPE_HOLDER1: {

return new Holder1(LayoutInflater.from(context).inflate(R.layout.view1, parent, false));

}

default: throw new RuntimeException("Not support type" + viewType);
}

}

}
Add ViewHolder
public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

protected static final int TYPE_HOLDER1 = 1;

protected static final int TYPE_HOLDER2 = 2;

@Override

public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

switch (viewType) {

case TYPE_HOLDER1: {

return new Holder1(LayoutInflater.from(context).inflate(R.layout.view1, parent, false));

}

case TYPE_HOLDER2: {

return new Holder2(LayoutInflater.from(context).inflate(R.layout.view2, parent, false));

}

default: throw new RuntimeException("Not support type" + viewType);
}

}

}
Add more ViewHolder
public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

protected static final int TYPE_HOLDER1 = 1;

protected static final int TYPE_HOLDER2 = 2;

protected static final int TYPE_HOLDER3 = 3;

@Override

public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

switch (viewType) {

case TYPE_HOLDER1: {

return new Holder1(LayoutInflater.from(context).inflate(R.layout.view1, parent, false));

}

case TYPE_HOLDER2: {

return new Holder2(LayoutInflater.from(context).inflate(R.layout.view2, parent, false));

}

case TYPE_HOLDER3: {

return new Holder3(LayoutInflater.from(context).inflate(R.layout.view3, parent, false));

}

default: throw new RuntimeException("Not support type" + viewType);
}

}

}
Even more ViewHolders
public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

protected static final int TYPE_HOLDER1 = 1;

protected static final int TYPE_HOLDER2 = 2;

protected static final int TYPE_HOLDER3 = 3;

protected static final int TYPE_HOLDER4 = 4;

protected static final int TYPE_HOLDER5 = 5;

protected static final int TYPE_HOLDER6 = 6;

@Override

public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

switch (viewType) {

case TYPE_HOLDER1: {

return new Holder1(LayoutInflater.from(context).inflate(R.layout.view1, parent, false));

}

case TYPE_HOLDER2: {

return new Holder2(LayoutInflater.from(context).inflate(R.layout.view2, parent, false));

}

case TYPE_HOLDER3: {

return new Holder3(LayoutInflater.from(context).inflate(R.layout.view3, parent, false));

}

case TYPE_HOLDER4: {

return new Holder4(LayoutInflater.from(context).inflate(R.layout.view4, parent, false));

}

case TYPE_HOLDER5: {

return new Holder5(LayoutInflater.from(context).inflate(R.layout.view5, parent, false));

}

case TYPE_HOLDER6: {

return new Holder6(LayoutInflater.from(context).inflate(R.layout.view6, parent, false));

}

default: throw new RuntimeException("Not support type" + viewType);

}

}

}
Even more Adapters
public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

protected static final int TYPE_HOLDER1 = 1;

protected static final int TYPE_HOLDER2 = 2;

protected static final int TYPE_HOLDER3 = 3;

protected static final int TYPE_HOLDER4 = 4;

protected static final int TYPE_HOLDER5 = 5;

protected static final int TYPE_HOLDER6 = 6;

@Override

public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

switch (viewType) {

case TYPE_HOLDER1: {

return new Holder1(LayoutInflater.from(context).inflate(R.layout.view1, parent, false));

}

case TYPE_HOLDER2: {

return new Holder2(LayoutInflater.from(context).inflate(R.layout.view2, parent, false));

}

case TYPE_HOLDER3: {

return new Holder3(LayoutInflater.from(context).inflate(R.layout.view3, parent, false));

}

case TYPE_HOLDER4: {

return new Holder4(LayoutInflater.from(context).inflate(R.layout.view4, parent, false));

}

case TYPE_HOLDER5: {

return new Holder5(LayoutInflater.from(context).inflate(R.layout.view5, parent, false));

}

case TYPE_HOLDER6: {

return new Holder6(LayoutInflater.from(context).inflate(R.layout.view6, parent, false));

}

default: throw new RuntimeException("Not support type" + viewType);

}

}

}

public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

protected static final int TYPE_HOLDER1 = 1;

protected static final int TYPE_HOLDER2 = 2;

protected static final int TYPE_HOLDER3 = 3;

protected static final int TYPE_HOLDER4 = 4;

protected static final int TYPE_HOLDER5 = 5;

protected static final int TYPE_HOLDER6 = 6;

@Override

public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

switch (viewType) {

case TYPE_HOLDER1: {

return new Holder1(LayoutInflater.from(context).inflate(R.layout.view1, parent, false));

}

case TYPE_HOLDER2: {

return new Holder2(LayoutInflater.from(context).inflate(R.layout.view2, parent, false));

}

case TYPE_HOLDER3: {

return new Holder3(LayoutInflater.from(context).inflate(R.layout.view3, parent, false));

}

case TYPE_HOLDER4: {

return new Holder4(LayoutInflater.from(context).inflate(R.layout.view4, parent, false));

}

case TYPE_HOLDER5: {

return new Holder5(LayoutInflater.from(context).inflate(R.layout.view5, parent, false));

}

case TYPE_HOLDER6: {

return new Holder6(LayoutInflater.from(context).inflate(R.layout.view6, parent, false));

}

default: throw new RuntimeException("Not support type" + viewType);

}

}

}
Annotation Processing
@BindHolder(Holder1.class)

@BindHolder(Holder2.class)

@BindHolder(Holder3.class, R.layout.view3)

@BindHolder(Holder4.class, R.layout.view4)

public class MyAdapter extends MyAdapterHelper {}

@BindLayout(R.layout.item_holder1)

class ViewHolder1 extends RecyclerView.ViewHolder {}

@BindLayout(R.layout.item_holder2)

class ViewHolder2 extends RecyclerView.ViewHolder {}

// https://github.com/Jintin/ComposeAdapter
Reference
https://kotlinlang.org/docs/reference/annotations.html

https://docs.oracle.com/javase/8/docs/api/javax/annotation/processing/
Processor.html

https://docs.oracle.com/javase/8/docs/api/javax/lang/model/element/
Element.html

https://kotlinlang.org/docs/reference/kapt.html

https://github.com/gradle/gradle/blob/master/subprojects/docs/src/docs/
userguide/java_plugin.adoc#state-of-support-in-popular-annotation-
processors

https://medium.com/@jintin/annotation-processing-in-java-3621cb05343a
Reference
https://github.com/google/auto/tree/master/service

https://github.com/square/javapoet

https://github.com/square/kotlinpoet

https://github.com/Jintin/ComposeAdapter

https://github.com/Jintin/AutoFactory
Q&A

More Related Content

What's hot

Are app servers still fascinating
Are app servers still fascinatingAre app servers still fascinating
Are app servers still fascinatingAntonio Goncalves
 
When Enterprise Java Micro Profile meets Angular
When Enterprise Java Micro Profile meets AngularWhen Enterprise Java Micro Profile meets Angular
When Enterprise Java Micro Profile meets AngularAntonio Goncalves
 
Jdk 7 4-forkjoin
Jdk 7 4-forkjoinJdk 7 4-forkjoin
Jdk 7 4-forkjoinknight1128
 
Python Evolution
Python EvolutionPython Evolution
Python EvolutionQuintagroup
 
Code generation for alternative languages
Code generation for alternative languagesCode generation for alternative languages
Code generation for alternative languagesRafael Winterhalter
 
Overview of Android Infrastructure
Overview of Android InfrastructureOverview of Android Infrastructure
Overview of Android InfrastructureAlexey Buzdin
 
Explanation onAttach() of Fragment class in Android
Explanation onAttach() of Fragment class in AndroidExplanation onAttach() of Fragment class in Android
Explanation onAttach() of Fragment class in Androidyuchi_1k91 Pit
 
Introduction to CDI and DI in Java EE 6
Introduction to CDI and DI in Java EE 6Introduction to CDI and DI in Java EE 6
Introduction to CDI and DI in Java EE 6Ray Ploski
 
50 new features of Java EE 7 in 50 minutes
50 new features of Java EE 7 in 50 minutes50 new features of Java EE 7 in 50 minutes
50 new features of Java EE 7 in 50 minutesAntonio Goncalves
 
Getting started with Java 9 modules
Getting started with Java 9 modulesGetting started with Java 9 modules
Getting started with Java 9 modulesRafael Winterhalter
 
Making Java more dynamic: runtime code generation for the JVM
Making Java more dynamic: runtime code generation for the JVMMaking Java more dynamic: runtime code generation for the JVM
Making Java more dynamic: runtime code generation for the JVMRafael Winterhalter
 
Why Spring <3 Kotlin
Why Spring <3 KotlinWhy Spring <3 Kotlin
Why Spring <3 KotlinVMware Tanzu
 
Concurrency and Thread-Safe Data Processing in Background Tasks
Concurrency and Thread-Safe Data Processing in Background TasksConcurrency and Thread-Safe Data Processing in Background Tasks
Concurrency and Thread-Safe Data Processing in Background TasksWO Community
 
Con-FESS 2015 - Having Fun With Javassist
Con-FESS 2015 - Having Fun With JavassistCon-FESS 2015 - Having Fun With Javassist
Con-FESS 2015 - Having Fun With JavassistAnton Arhipov
 
Developing Useful APIs
Developing Useful APIsDeveloping Useful APIs
Developing Useful APIsDmitry Buzdin
 
Developing components and extensions for ext js
Developing components and extensions for ext jsDeveloping components and extensions for ext js
Developing components and extensions for ext jsMats Bryntse
 

What's hot (20)

Are app servers still fascinating
Are app servers still fascinatingAre app servers still fascinating
Are app servers still fascinating
 
When Enterprise Java Micro Profile meets Angular
When Enterprise Java Micro Profile meets AngularWhen Enterprise Java Micro Profile meets Angular
When Enterprise Java Micro Profile meets Angular
 
Jdk 7 4-forkjoin
Jdk 7 4-forkjoinJdk 7 4-forkjoin
Jdk 7 4-forkjoin
 
Python Evolution
Python EvolutionPython Evolution
Python Evolution
 
Code generation for alternative languages
Code generation for alternative languagesCode generation for alternative languages
Code generation for alternative languages
 
Overview of Android Infrastructure
Overview of Android InfrastructureOverview of Android Infrastructure
Overview of Android Infrastructure
 
Explanation onAttach() of Fragment class in Android
Explanation onAttach() of Fragment class in AndroidExplanation onAttach() of Fragment class in Android
Explanation onAttach() of Fragment class in Android
 
Introduction to CDI and DI in Java EE 6
Introduction to CDI and DI in Java EE 6Introduction to CDI and DI in Java EE 6
Introduction to CDI and DI in Java EE 6
 
50 new features of Java EE 7 in 50 minutes
50 new features of Java EE 7 in 50 minutes50 new features of Java EE 7 in 50 minutes
50 new features of Java EE 7 in 50 minutes
 
Getting started with Java 9 modules
Getting started with Java 9 modulesGetting started with Java 9 modules
Getting started with Java 9 modules
 
Making Java more dynamic: runtime code generation for the JVM
Making Java more dynamic: runtime code generation for the JVMMaking Java more dynamic: runtime code generation for the JVM
Making Java more dynamic: runtime code generation for the JVM
 
Why Spring <3 Kotlin
Why Spring <3 KotlinWhy Spring <3 Kotlin
Why Spring <3 Kotlin
 
ExtJs Basic Part-1
ExtJs Basic Part-1ExtJs Basic Part-1
ExtJs Basic Part-1
 
Concurrency and Thread-Safe Data Processing in Background Tasks
Concurrency and Thread-Safe Data Processing in Background TasksConcurrency and Thread-Safe Data Processing in Background Tasks
Concurrency and Thread-Safe Data Processing in Background Tasks
 
Con-FESS 2015 - Having Fun With Javassist
Con-FESS 2015 - Having Fun With JavassistCon-FESS 2015 - Having Fun With Javassist
Con-FESS 2015 - Having Fun With Javassist
 
Java Enterprise Edition
Java Enterprise EditionJava Enterprise Edition
Java Enterprise Edition
 
Spring boot
Spring bootSpring boot
Spring boot
 
Developing Useful APIs
Developing Useful APIsDeveloping Useful APIs
Developing Useful APIs
 
Developing components and extensions for ext js
Developing components and extensions for ext jsDeveloping components and extensions for ext js
Developing components and extensions for ext js
 
Enterprise js pratices
Enterprise js praticesEnterprise js pratices
Enterprise js pratices
 

Similar to Annotation Processing

Workshop 23: ReactJS, React & Redux testing
Workshop 23: ReactJS, React & Redux testingWorkshop 23: ReactJS, React & Redux testing
Workshop 23: ReactJS, React & Redux testingVisual Engineering
 
TypeScript for Java Developers
TypeScript for Java DevelopersTypeScript for Java Developers
TypeScript for Java DevelopersYakov Fain
 
Back-2-Basics: .NET Coding Standards For The Real World (2011)
Back-2-Basics: .NET Coding Standards For The Real World (2011)Back-2-Basics: .NET Coding Standards For The Real World (2011)
Back-2-Basics: .NET Coding Standards For The Real World (2011)David McCarter
 
Testable JavaScript: Application Architecture
Testable JavaScript:  Application ArchitectureTestable JavaScript:  Application Architecture
Testable JavaScript: Application ArchitectureMark Trostler
 
Stencil the time for vanilla web components has arrived
Stencil the time for vanilla web components has arrivedStencil the time for vanilla web components has arrived
Stencil the time for vanilla web components has arrivedGil Fink
 
Daggerate your code - Write your own annotation processor
Daggerate your code - Write your own annotation processorDaggerate your code - Write your own annotation processor
Daggerate your code - Write your own annotation processorBartosz Kosarzycki
 
The Naked Bundle - Tryout
The Naked Bundle - TryoutThe Naked Bundle - Tryout
The Naked Bundle - TryoutMatthias Noback
 
Introduction to Griffon
Introduction to GriffonIntroduction to Griffon
Introduction to GriffonJames Williams
 
Bring the fun back to java
Bring the fun back to javaBring the fun back to java
Bring the fun back to javaciklum_ods
 
The Naked Bundle - Symfony Live London 2014
The Naked Bundle - Symfony Live London 2014The Naked Bundle - Symfony Live London 2014
The Naked Bundle - Symfony Live London 2014Matthias Noback
 
Whoops! where did my architecture go?
Whoops! where did my architecture go?Whoops! where did my architecture go?
Whoops! where did my architecture go?Oliver Gierke
 
Testing of javacript
Testing of javacriptTesting of javacript
Testing of javacriptLei Kang
 
Stencil: The Time for Vanilla Web Components has Arrived
Stencil: The Time for Vanilla Web Components has ArrivedStencil: The Time for Vanilla Web Components has Arrived
Stencil: The Time for Vanilla Web Components has ArrivedGil Fink
 
Angular 2 for Java Developers
Angular 2 for Java DevelopersAngular 2 for Java Developers
Angular 2 for Java DevelopersYakov Fain
 
Jollen's Presentation: Introducing Android low-level
Jollen's Presentation: Introducing Android low-levelJollen's Presentation: Introducing Android low-level
Jollen's Presentation: Introducing Android low-levelJollen Chen
 
How React Native, Appium and me made each other shine @Frontmania 16-11-2018
How React Native, Appium and me made each other shine @Frontmania 16-11-2018How React Native, Appium and me made each other shine @Frontmania 16-11-2018
How React Native, Appium and me made each other shine @Frontmania 16-11-2018Wim Selles
 
Google Web Toolkits
Google Web ToolkitsGoogle Web Toolkits
Google Web ToolkitsYiguang Hu
 
Protractor framework architecture with example
Protractor framework architecture with exampleProtractor framework architecture with example
Protractor framework architecture with exampleshadabgilani
 
Commenting in Agile Development
Commenting in Agile DevelopmentCommenting in Agile Development
Commenting in Agile DevelopmentJan Rybák Benetka
 

Similar to Annotation Processing (20)

Workshop 23: ReactJS, React & Redux testing
Workshop 23: ReactJS, React & Redux testingWorkshop 23: ReactJS, React & Redux testing
Workshop 23: ReactJS, React & Redux testing
 
TypeScript for Java Developers
TypeScript for Java DevelopersTypeScript for Java Developers
TypeScript for Java Developers
 
Back-2-Basics: .NET Coding Standards For The Real World (2011)
Back-2-Basics: .NET Coding Standards For The Real World (2011)Back-2-Basics: .NET Coding Standards For The Real World (2011)
Back-2-Basics: .NET Coding Standards For The Real World (2011)
 
Testable JavaScript: Application Architecture
Testable JavaScript:  Application ArchitectureTestable JavaScript:  Application Architecture
Testable JavaScript: Application Architecture
 
Stencil the time for vanilla web components has arrived
Stencil the time for vanilla web components has arrivedStencil the time for vanilla web components has arrived
Stencil the time for vanilla web components has arrived
 
Daggerate your code - Write your own annotation processor
Daggerate your code - Write your own annotation processorDaggerate your code - Write your own annotation processor
Daggerate your code - Write your own annotation processor
 
The Naked Bundle - Tryout
The Naked Bundle - TryoutThe Naked Bundle - Tryout
The Naked Bundle - Tryout
 
Introduction to Griffon
Introduction to GriffonIntroduction to Griffon
Introduction to Griffon
 
Bring the fun back to java
Bring the fun back to javaBring the fun back to java
Bring the fun back to java
 
The Naked Bundle - Symfony Live London 2014
The Naked Bundle - Symfony Live London 2014The Naked Bundle - Symfony Live London 2014
The Naked Bundle - Symfony Live London 2014
 
Whoops! where did my architecture go?
Whoops! where did my architecture go?Whoops! where did my architecture go?
Whoops! where did my architecture go?
 
Testing of javacript
Testing of javacriptTesting of javacript
Testing of javacript
 
Stencil: The Time for Vanilla Web Components has Arrived
Stencil: The Time for Vanilla Web Components has ArrivedStencil: The Time for Vanilla Web Components has Arrived
Stencil: The Time for Vanilla Web Components has Arrived
 
C# 6.0 Preview
C# 6.0 PreviewC# 6.0 Preview
C# 6.0 Preview
 
Angular 2 for Java Developers
Angular 2 for Java DevelopersAngular 2 for Java Developers
Angular 2 for Java Developers
 
Jollen's Presentation: Introducing Android low-level
Jollen's Presentation: Introducing Android low-levelJollen's Presentation: Introducing Android low-level
Jollen's Presentation: Introducing Android low-level
 
How React Native, Appium and me made each other shine @Frontmania 16-11-2018
How React Native, Appium and me made each other shine @Frontmania 16-11-2018How React Native, Appium and me made each other shine @Frontmania 16-11-2018
How React Native, Appium and me made each other shine @Frontmania 16-11-2018
 
Google Web Toolkits
Google Web ToolkitsGoogle Web Toolkits
Google Web Toolkits
 
Protractor framework architecture with example
Protractor framework architecture with exampleProtractor framework architecture with example
Protractor framework architecture with example
 
Commenting in Agile Development
Commenting in Agile DevelopmentCommenting in Agile Development
Commenting in Agile Development
 

More from Jintin Lin

我的開源之旅
我的開源之旅我的開源之旅
我的開源之旅Jintin Lin
 
Dagger 2 vs koin
Dagger 2 vs koinDagger 2 vs koin
Dagger 2 vs koinJintin Lin
 
數學系的資訊人生
數學系的資訊人生數學系的資訊人生
數學系的資訊人生Jintin Lin
 
Instant app Intro
Instant app IntroInstant app Intro
Instant app IntroJintin Lin
 
KVO implementation
KVO implementationKVO implementation
KVO implementationJintin Lin
 
iOS NotificationCenter intro
iOS NotificationCenter introiOS NotificationCenter intro
iOS NotificationCenter introJintin Lin
 
App design guide
App design guideApp design guide
App design guideJintin Lin
 
Swimat - Swift formatter
Swimat - Swift formatterSwimat - Swift formatter
Swimat - Swift formatterJintin Lin
 
Swift Tutorial 2
Swift Tutorial  2Swift Tutorial  2
Swift Tutorial 2Jintin Lin
 
Swift Tutorial 1
Swift Tutorial 1Swift Tutorial 1
Swift Tutorial 1Jintin Lin
 
Realism vs Flat design
Realism vs Flat designRealism vs Flat design
Realism vs Flat designJintin Lin
 
Android Service Intro
Android Service IntroAndroid Service Intro
Android Service IntroJintin Lin
 

More from Jintin Lin (17)

KSP intro
KSP introKSP intro
KSP intro
 
我的開源之旅
我的開源之旅我的開源之旅
我的開源之旅
 
Dagger 2 vs koin
Dagger 2 vs koinDagger 2 vs koin
Dagger 2 vs koin
 
ButterKnife
ButterKnifeButterKnife
ButterKnife
 
數學系的資訊人生
數學系的資訊人生數學系的資訊人生
數學系的資訊人生
 
Instant app Intro
Instant app IntroInstant app Intro
Instant app Intro
 
KVO implementation
KVO implementationKVO implementation
KVO implementation
 
iOS NotificationCenter intro
iOS NotificationCenter introiOS NotificationCenter intro
iOS NotificationCenter intro
 
App design guide
App design guideApp design guide
App design guide
 
J霧霾
J霧霾J霧霾
J霧霾
 
transai
transaitransai
transai
 
Swimat - Swift formatter
Swimat - Swift formatterSwimat - Swift formatter
Swimat - Swift formatter
 
Swift Tutorial 2
Swift Tutorial  2Swift Tutorial  2
Swift Tutorial 2
 
Swift Tutorial 1
Swift Tutorial 1Swift Tutorial 1
Swift Tutorial 1
 
Andle
AndleAndle
Andle
 
Realism vs Flat design
Realism vs Flat designRealism vs Flat design
Realism vs Flat design
 
Android Service Intro
Android Service IntroAndroid Service Intro
Android Service Intro
 

Recently uploaded

HARMONY IN THE NATURE AND EXISTENCE - Unit-IV
HARMONY IN THE NATURE AND EXISTENCE - Unit-IVHARMONY IN THE NATURE AND EXISTENCE - Unit-IV
HARMONY IN THE NATURE AND EXISTENCE - Unit-IVRajaP95
 
High Profile Call Girls Nagpur Meera Call 7001035870 Meet With Nagpur Escorts
High Profile Call Girls Nagpur Meera Call 7001035870 Meet With Nagpur EscortsHigh Profile Call Girls Nagpur Meera Call 7001035870 Meet With Nagpur Escorts
High Profile Call Girls Nagpur Meera Call 7001035870 Meet With Nagpur EscortsCall Girls in Nagpur High Profile
 
VIP Call Girls Service Hitech City Hyderabad Call +91-8250192130
VIP Call Girls Service Hitech City Hyderabad Call +91-8250192130VIP Call Girls Service Hitech City Hyderabad Call +91-8250192130
VIP Call Girls Service Hitech City Hyderabad Call +91-8250192130Suhani Kapoor
 
Analog to Digital and Digital to Analog Converter
Analog to Digital and Digital to Analog ConverterAnalog to Digital and Digital to Analog Converter
Analog to Digital and Digital to Analog ConverterAbhinavSharma374939
 
(RIA) Call Girls Bhosari ( 7001035870 ) HI-Fi Pune Escorts Service
(RIA) Call Girls Bhosari ( 7001035870 ) HI-Fi Pune Escorts Service(RIA) Call Girls Bhosari ( 7001035870 ) HI-Fi Pune Escorts Service
(RIA) Call Girls Bhosari ( 7001035870 ) HI-Fi Pune Escorts Serviceranjana rawat
 
Model Call Girl in Narela Delhi reach out to us at 🔝8264348440🔝
Model Call Girl in Narela Delhi reach out to us at 🔝8264348440🔝Model Call Girl in Narela Delhi reach out to us at 🔝8264348440🔝
Model Call Girl in Narela Delhi reach out to us at 🔝8264348440🔝soniya singh
 
Sheet Pile Wall Design and Construction: A Practical Guide for Civil Engineer...
Sheet Pile Wall Design and Construction: A Practical Guide for Civil Engineer...Sheet Pile Wall Design and Construction: A Practical Guide for Civil Engineer...
Sheet Pile Wall Design and Construction: A Practical Guide for Civil Engineer...Dr.Costas Sachpazis
 
Call Girls in Nagpur Suman Call 7001035870 Meet With Nagpur Escorts
Call Girls in Nagpur Suman Call 7001035870 Meet With Nagpur EscortsCall Girls in Nagpur Suman Call 7001035870 Meet With Nagpur Escorts
Call Girls in Nagpur Suman Call 7001035870 Meet With Nagpur EscortsCall Girls in Nagpur High Profile
 
Call Girls Delhi {Jodhpur} 9711199012 high profile service
Call Girls Delhi {Jodhpur} 9711199012 high profile serviceCall Girls Delhi {Jodhpur} 9711199012 high profile service
Call Girls Delhi {Jodhpur} 9711199012 high profile servicerehmti665
 
Software Development Life Cycle By Team Orange (Dept. of Pharmacy)
Software Development Life Cycle By  Team Orange (Dept. of Pharmacy)Software Development Life Cycle By  Team Orange (Dept. of Pharmacy)
Software Development Life Cycle By Team Orange (Dept. of Pharmacy)Suman Mia
 
Decoding Kotlin - Your guide to solving the mysterious in Kotlin.pptx
Decoding Kotlin - Your guide to solving the mysterious in Kotlin.pptxDecoding Kotlin - Your guide to solving the mysterious in Kotlin.pptx
Decoding Kotlin - Your guide to solving the mysterious in Kotlin.pptxJoão Esperancinha
 
The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...
The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...
The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...ranjana rawat
 
Call Girls Service Nagpur Tanvi Call 7001035870 Meet With Nagpur Escorts
Call Girls Service Nagpur Tanvi Call 7001035870 Meet With Nagpur EscortsCall Girls Service Nagpur Tanvi Call 7001035870 Meet With Nagpur Escorts
Call Girls Service Nagpur Tanvi Call 7001035870 Meet With Nagpur EscortsCall Girls in Nagpur High Profile
 
Microscopic Analysis of Ceramic Materials.pptx
Microscopic Analysis of Ceramic Materials.pptxMicroscopic Analysis of Ceramic Materials.pptx
Microscopic Analysis of Ceramic Materials.pptxpurnimasatapathy1234
 
(SHREYA) Chakan Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Esc...
(SHREYA) Chakan Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Esc...(SHREYA) Chakan Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Esc...
(SHREYA) Chakan Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Esc...ranjana rawat
 
(MEERA) Dapodi Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Escorts
(MEERA) Dapodi Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Escorts(MEERA) Dapodi Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Escorts
(MEERA) Dapodi Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Escortsranjana rawat
 
(ANVI) Koregaon Park Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(ANVI) Koregaon Park Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...(ANVI) Koregaon Park Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(ANVI) Koregaon Park Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...ranjana rawat
 
(PRIYA) Rajgurunagar Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(PRIYA) Rajgurunagar Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...(PRIYA) Rajgurunagar Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(PRIYA) Rajgurunagar Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...ranjana rawat
 

Recently uploaded (20)

HARMONY IN THE NATURE AND EXISTENCE - Unit-IV
HARMONY IN THE NATURE AND EXISTENCE - Unit-IVHARMONY IN THE NATURE AND EXISTENCE - Unit-IV
HARMONY IN THE NATURE AND EXISTENCE - Unit-IV
 
High Profile Call Girls Nagpur Meera Call 7001035870 Meet With Nagpur Escorts
High Profile Call Girls Nagpur Meera Call 7001035870 Meet With Nagpur EscortsHigh Profile Call Girls Nagpur Meera Call 7001035870 Meet With Nagpur Escorts
High Profile Call Girls Nagpur Meera Call 7001035870 Meet With Nagpur Escorts
 
VIP Call Girls Service Hitech City Hyderabad Call +91-8250192130
VIP Call Girls Service Hitech City Hyderabad Call +91-8250192130VIP Call Girls Service Hitech City Hyderabad Call +91-8250192130
VIP Call Girls Service Hitech City Hyderabad Call +91-8250192130
 
Analog to Digital and Digital to Analog Converter
Analog to Digital and Digital to Analog ConverterAnalog to Digital and Digital to Analog Converter
Analog to Digital and Digital to Analog Converter
 
(RIA) Call Girls Bhosari ( 7001035870 ) HI-Fi Pune Escorts Service
(RIA) Call Girls Bhosari ( 7001035870 ) HI-Fi Pune Escorts Service(RIA) Call Girls Bhosari ( 7001035870 ) HI-Fi Pune Escorts Service
(RIA) Call Girls Bhosari ( 7001035870 ) HI-Fi Pune Escorts Service
 
Model Call Girl in Narela Delhi reach out to us at 🔝8264348440🔝
Model Call Girl in Narela Delhi reach out to us at 🔝8264348440🔝Model Call Girl in Narela Delhi reach out to us at 🔝8264348440🔝
Model Call Girl in Narela Delhi reach out to us at 🔝8264348440🔝
 
Sheet Pile Wall Design and Construction: A Practical Guide for Civil Engineer...
Sheet Pile Wall Design and Construction: A Practical Guide for Civil Engineer...Sheet Pile Wall Design and Construction: A Practical Guide for Civil Engineer...
Sheet Pile Wall Design and Construction: A Practical Guide for Civil Engineer...
 
Call Girls in Nagpur Suman Call 7001035870 Meet With Nagpur Escorts
Call Girls in Nagpur Suman Call 7001035870 Meet With Nagpur EscortsCall Girls in Nagpur Suman Call 7001035870 Meet With Nagpur Escorts
Call Girls in Nagpur Suman Call 7001035870 Meet With Nagpur Escorts
 
Call Girls Delhi {Jodhpur} 9711199012 high profile service
Call Girls Delhi {Jodhpur} 9711199012 high profile serviceCall Girls Delhi {Jodhpur} 9711199012 high profile service
Call Girls Delhi {Jodhpur} 9711199012 high profile service
 
Software Development Life Cycle By Team Orange (Dept. of Pharmacy)
Software Development Life Cycle By  Team Orange (Dept. of Pharmacy)Software Development Life Cycle By  Team Orange (Dept. of Pharmacy)
Software Development Life Cycle By Team Orange (Dept. of Pharmacy)
 
Decoding Kotlin - Your guide to solving the mysterious in Kotlin.pptx
Decoding Kotlin - Your guide to solving the mysterious in Kotlin.pptxDecoding Kotlin - Your guide to solving the mysterious in Kotlin.pptx
Decoding Kotlin - Your guide to solving the mysterious in Kotlin.pptx
 
The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...
The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...
The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...
 
Roadmap to Membership of RICS - Pathways and Routes
Roadmap to Membership of RICS - Pathways and RoutesRoadmap to Membership of RICS - Pathways and Routes
Roadmap to Membership of RICS - Pathways and Routes
 
Call Girls Service Nagpur Tanvi Call 7001035870 Meet With Nagpur Escorts
Call Girls Service Nagpur Tanvi Call 7001035870 Meet With Nagpur EscortsCall Girls Service Nagpur Tanvi Call 7001035870 Meet With Nagpur Escorts
Call Girls Service Nagpur Tanvi Call 7001035870 Meet With Nagpur Escorts
 
Microscopic Analysis of Ceramic Materials.pptx
Microscopic Analysis of Ceramic Materials.pptxMicroscopic Analysis of Ceramic Materials.pptx
Microscopic Analysis of Ceramic Materials.pptx
 
(SHREYA) Chakan Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Esc...
(SHREYA) Chakan Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Esc...(SHREYA) Chakan Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Esc...
(SHREYA) Chakan Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Esc...
 
(MEERA) Dapodi Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Escorts
(MEERA) Dapodi Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Escorts(MEERA) Dapodi Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Escorts
(MEERA) Dapodi Call Girls Just Call 7001035870 [ Cash on Delivery ] Pune Escorts
 
(ANVI) Koregaon Park Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(ANVI) Koregaon Park Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...(ANVI) Koregaon Park Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(ANVI) Koregaon Park Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
 
DJARUM4D - SLOT GACOR ONLINE | SLOT DEMO ONLINE
DJARUM4D - SLOT GACOR ONLINE | SLOT DEMO ONLINEDJARUM4D - SLOT GACOR ONLINE | SLOT DEMO ONLINE
DJARUM4D - SLOT GACOR ONLINE | SLOT DEMO ONLINE
 
(PRIYA) Rajgurunagar Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(PRIYA) Rajgurunagar Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...(PRIYA) Rajgurunagar Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
(PRIYA) Rajgurunagar Call Girls Just Call 7001035870 [ Cash on Delivery ] Pun...
 

Annotation Processing

  • 2. About me Tim / Jintin Android / iOS developer Senior Software Engineer 
 @ Carousell https://github.com/Jintin https://medium.com/@Jintin
  • 4.
  • 5.
  • 6.
  • 9. “Annotation Processing is a tool we can use to help us generate code in compile time by labeling Annotations inside our source code.”
  • 10. Pros & Cons + Less boilerplate code + No Runtime Error - Block incremental build - Kotlin 1.3.30+ - Gradle 4.7+ - Compile overhead
  • 14. How we use it dependencies { implementation 'com.google.dagger:dagger:2.x' kapt ‘com.google.dagger:dagger-compiler:2.x' } kapt stands for Kotlin annotation processing tool
  • 15. Module structure Library module (optional) Processor(compiler) module Annotation module
  • 18. Attribute @GET(“XXX_Value") Observable getAPI(); @Component(modules = { AModule.class, BModule.class, CModule.class}) public interface MyComponent {}
  • 19. Attribute @Target(METHOD) @Retention(RUNTIME) public @interface GET { String value() default ""; } @Retention(RUNTIME) @Target(TYPE) public @interface Component { Class<?>[] modules() default {}; Class<?>[] dependencies() default {}; }
  • 20. Attribute Primitive types (int, long, etc.) String Classes (Foo::class) Enums Other annotations Arrays of the types listed above.
  • 24. Retention @Target(ElementType.METHOD) @Retention(SOURCE) public @interface Override {} @Target({ METHOD, CONSTRUCTOR, FIELD }) @Retention(RUNTIME) public @interface Inject {}
  • 25. Retention public enum RetentionPolicy { /* only exist before compile finish. */ SOURCE, /* recorded in the class file by the compiler but need not be retained by the VM at run time. */ CLASS, /* to be recorded in the class file and can be used at run time, so they may be read reflectively. */ RUNTIME }
  • 26. Retention public enum RetentionPolicy { /* only exist before compile finish. */ SOURCE, /* recorded in the class file by the compiler but need not be retained by the VM at run time. */ CLASS, /* to be recorded in the class file and can be used at run time, so they may be read reflectively. */ RUNTIME }
  • 27. Retention public enum RetentionPolicy { /* only exist before compile finish. */ SOURCE, /* recorded in the class file by the compiler but need not be retained by the VM at run time. */ CLASS, /* to be recorded in the class file and can be used at run time, so they may be read reflectively. */ RUNTIME }
  • 28. Retention public enum RetentionPolicy { /* only exist before compile finish. */ SOURCE, /* recorded in the class file by the compiler but need not be retained by the VM at run time. */ CLASS, /* to be recorded in the class file and can be used at run time, so they may be read reflectively. */ RUNTIME }
  • 29. Processor module Only used in compile phase. Not include in final Jar/Apk. Can contain several Processors.
  • 30. Hook
  • 31. AutoService Hook @AutoService(Processor::class) class AdapterProcessor : Processor() 
 dependencies { implementation ‘com.google.auto.service:auto-service:1.X’ }
  • 32. public interface Processor { /** Initializes with the processing environment. */ void init(ProcessingEnvironment processingEnv); /** Returns the target the annotation types to process. */ Set<String> getSupportedAnnotationTypes(); /** Processes a set of annotation on type elements. */ boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnv); … } Processor
  • 33. public interface Processor { /** Initializes with the processing environment. */ void init(ProcessingEnvironment processingEnv); /** Returns the target the annotation types to process. */ Set<String> getSupportedAnnotationTypes(); /** Processes a set of annotation on type elements. */ boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnv); … } Processor
  • 34. public interface Processor { /** Initializes with the processing environment. */ void init(ProcessingEnvironment processingEnv); /** Returns the target the annotation types to process. */ Set<String> getSupportedAnnotationTypes(); /** Processes a set of annotation on type elements. */ boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnv); … } Processor
  • 35. public interface Processor { /** Initializes with the processing environment. */ void init(ProcessingEnvironment processingEnv); /** Returns the target the annotation types to process. */ Set<String> getSupportedAnnotationTypes(); /** Processes a set of annotation on type elements. */ boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnv); … } Processor
  • 36. Element Unit of code element. - PackageElement: Package - TypeElement: Class, Interface - ExecutableElement: Method, Constructor
  • 37. @Override public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnv) { for (Element element : roundEnv.getElementsAnnotatedWith(MyAnnotation.class)) { if (element.getKind() != ElementKind.INTERFACE) { error("Only interface can be used with MyAnnotation", element); return true; } TypeElement typeElement = (TypeElement) element; typeElement.getInterfaces(); typeElement.getSuperclass(); typeElement.getSimpleName(); MyAnnotation anno = element.getAnnotation(MyAnnotation.class); /** Custom logic to build the relation graph and generate the file*/ } return true; }
  • 38. @Override public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnv) { for (Element element : roundEnv.getElementsAnnotatedWith(MyAnnotation.class)) { if (element.getKind() != ElementKind.INTERFACE) { error("Only interface can be used with MyAnnotation", element); return true; } TypeElement typeElement = (TypeElement) element; typeElement.getInterfaces(); typeElement.getSuperclass(); typeElement.getSimpleName(); MyAnnotation anno = element.getAnnotation(MyAnnotation.class); /** Custom logic to build the relation graph and generate the file*/ } return true; }
  • 39. @Override public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnv) { for (Element element : roundEnv.getElementsAnnotatedWith(MyAnnotation.class)) { if (element.getKind() != ElementKind.INTERFACE) { error("Only interface can be used with MyAnnotation", element); return true; } TypeElement typeElement = (TypeElement) element; typeElement.getInterfaces(); typeElement.getSuperclass(); typeElement.getSimpleName(); MyAnnotation anno = element.getAnnotation(MyAnnotation.class); /** Custom logic to build the relation graph and generate the file*/ } return true; }
  • 40. @Override public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnv) { for (Element element : roundEnv.getElementsAnnotatedWith(MyAnnotation.class)) { if (element.getKind() != ElementKind.INTERFACE) { error("Only interface can be used with MyAnnotation", element); return true; } TypeElement typeElement = (TypeElement) element; typeElement.getInterfaces(); typeElement.getSuperclass(); typeElement.getSimpleName(); MyAnnotation anno = element.getAnnotation(MyAnnotation.class); /** Custom logic to build the relation graph and generate the file*/ } return true; }
  • 41. @Override public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnv) { for (Element element : roundEnv.getElementsAnnotatedWith(MyAnnotation.class)) { if (element.getKind() != ElementKind.INTERFACE) { error("Only interface can be used with MyAnnotation", element); return true; } TypeElement typeElement = (TypeElement) element; typeElement.getInterfaces(); typeElement.getSuperclass(); typeElement.getSimpleName(); MyAnnotation anno = element.getAnnotation(MyAnnotation.class); /** Custom logic to build the relation graph and generate the file*/ } return true; }
  • 42. How to create file?
  • 44. Filer @Override public synchronized void init(ProcessingEnvironment env) { super.init(env); filer = env.getFiler(); } @Override public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnv) { … filer.createSourceFile(“NewFile", element); }
  • 45. How to create code?
  • 46. JavaPoet/KotlinPoet Provide simple API to generate Java/Kotlin file Both Square open source projects Over 8000 stars in total
  • 47. MethodSpec main = MethodSpec.methodBuilder("main") .build(); JavaPoet
  • 48. MethodSpec main = MethodSpec.methodBuilder("main") .build();
 
 void main() { } JavaPoet
  • 49. MethodSpec main = MethodSpec.methodBuilder("main") .addParameter(String[].class, "args") .build();
 
 void main(String[] args) { } JavaPoet
  • 50. MethodSpec main = MethodSpec.methodBuilder("main") .addParameter(String[].class, "args") .addStatement("$T.out.println($S)", System.class, "Hello, JavaPoet!") .build();
 
 void main(String[] args) { System.out.println("Hello, JavaPoet!"); } JavaPoet
  • 51. MethodSpec main = MethodSpec.methodBuilder("main") .addParameter(String[].class, "args") .addStatement("$T.out.println($S)", System.class, “Hello, JavaPoet!")
 .addModifiers(Modifier.PUBLIC, Modifier.STATIC) .build();
 
 public static void main(String[] args) { System.out.println("Hello, JavaPoet!"); } JavaPoet
  • 52. TypeSpec helloWorld = TypeSpec.classBuilder("HellowWorld") .addMethod(MethodSpec.{…}) .addModifiers(Modifier.PUBLIC, Modifier.FINAL) .build(); public final class HelloWorld { public static void main(String[] args) { System.out.println("Hello, JavaPoet!"); } } JavaPoet
  • 53. Tips Find the boilerplate of daily work, eg: findViewById, dependency graph, deep link, etc. Find the pattern and define each component. Label each component with annotation. Create processor to generate code and link each component.
  • 55. Factory public interface Animal {} public class Cat implements Animal {} public class Dog implements Animal {} public final class AnimalFactory { public static Animal createAnimal(String type) { switch(type) { case "cat": return new Cat(); case "dog": return new Dog(); } throw new RuntimeException("not support type"); } }
  • 56. Factory public interface Animal {} public class Cat implements Animal {} public class Dog implements Animal {} public final class AnimalFactory { public static Animal createAnimal(String type) { switch(type) { case "cat": return new Cat(); case "dog": return new Dog(); } throw new RuntimeException("not support type"); } }
  • 57. Auto Generate? @AutoFactory public interface Animal {} 
 @AutoElement(AnimalTags.CAT) public class Cat implements Animal {} @AutoElement(AnimalTags.DOG) public class Dog implements Animal {} // https://github.com/Jintin/AutoFactory
  • 59. 1 ViewHolder public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { protected static final int TYPE_HOLDER1 = 1; @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { switch (viewType) { case TYPE_HOLDER1: { return new Holder1(LayoutInflater.from(context).inflate(R.layout.view1, parent, false)); } default: throw new RuntimeException("Not support type" + viewType); } } }
  • 60. Add ViewHolder public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { protected static final int TYPE_HOLDER1 = 1; protected static final int TYPE_HOLDER2 = 2; @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { switch (viewType) { case TYPE_HOLDER1: { return new Holder1(LayoutInflater.from(context).inflate(R.layout.view1, parent, false)); } case TYPE_HOLDER2: { return new Holder2(LayoutInflater.from(context).inflate(R.layout.view2, parent, false)); } default: throw new RuntimeException("Not support type" + viewType); } } }
  • 61. Add more ViewHolder public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { protected static final int TYPE_HOLDER1 = 1; protected static final int TYPE_HOLDER2 = 2; protected static final int TYPE_HOLDER3 = 3; @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { switch (viewType) { case TYPE_HOLDER1: { return new Holder1(LayoutInflater.from(context).inflate(R.layout.view1, parent, false)); } case TYPE_HOLDER2: { return new Holder2(LayoutInflater.from(context).inflate(R.layout.view2, parent, false)); } case TYPE_HOLDER3: { return new Holder3(LayoutInflater.from(context).inflate(R.layout.view3, parent, false)); } default: throw new RuntimeException("Not support type" + viewType); } } }
  • 62. Even more ViewHolders public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { protected static final int TYPE_HOLDER1 = 1; protected static final int TYPE_HOLDER2 = 2; protected static final int TYPE_HOLDER3 = 3; protected static final int TYPE_HOLDER4 = 4; protected static final int TYPE_HOLDER5 = 5; protected static final int TYPE_HOLDER6 = 6; @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { switch (viewType) { case TYPE_HOLDER1: { return new Holder1(LayoutInflater.from(context).inflate(R.layout.view1, parent, false)); } case TYPE_HOLDER2: { return new Holder2(LayoutInflater.from(context).inflate(R.layout.view2, parent, false)); } case TYPE_HOLDER3: { return new Holder3(LayoutInflater.from(context).inflate(R.layout.view3, parent, false)); } case TYPE_HOLDER4: { return new Holder4(LayoutInflater.from(context).inflate(R.layout.view4, parent, false)); } case TYPE_HOLDER5: { return new Holder5(LayoutInflater.from(context).inflate(R.layout.view5, parent, false)); } case TYPE_HOLDER6: { return new Holder6(LayoutInflater.from(context).inflate(R.layout.view6, parent, false)); } default: throw new RuntimeException("Not support type" + viewType); } } }
  • 63. Even more Adapters public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { protected static final int TYPE_HOLDER1 = 1; protected static final int TYPE_HOLDER2 = 2; protected static final int TYPE_HOLDER3 = 3; protected static final int TYPE_HOLDER4 = 4; protected static final int TYPE_HOLDER5 = 5; protected static final int TYPE_HOLDER6 = 6; @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { switch (viewType) { case TYPE_HOLDER1: { return new Holder1(LayoutInflater.from(context).inflate(R.layout.view1, parent, false)); } case TYPE_HOLDER2: { return new Holder2(LayoutInflater.from(context).inflate(R.layout.view2, parent, false)); } case TYPE_HOLDER3: { return new Holder3(LayoutInflater.from(context).inflate(R.layout.view3, parent, false)); } case TYPE_HOLDER4: { return new Holder4(LayoutInflater.from(context).inflate(R.layout.view4, parent, false)); } case TYPE_HOLDER5: { return new Holder5(LayoutInflater.from(context).inflate(R.layout.view5, parent, false)); } case TYPE_HOLDER6: { return new Holder6(LayoutInflater.from(context).inflate(R.layout.view6, parent, false)); } default: throw new RuntimeException("Not support type" + viewType); } } } public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { protected static final int TYPE_HOLDER1 = 1; protected static final int TYPE_HOLDER2 = 2; protected static final int TYPE_HOLDER3 = 3; protected static final int TYPE_HOLDER4 = 4; protected static final int TYPE_HOLDER5 = 5; protected static final int TYPE_HOLDER6 = 6; @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { switch (viewType) { case TYPE_HOLDER1: { return new Holder1(LayoutInflater.from(context).inflate(R.layout.view1, parent, false)); } case TYPE_HOLDER2: { return new Holder2(LayoutInflater.from(context).inflate(R.layout.view2, parent, false)); } case TYPE_HOLDER3: { return new Holder3(LayoutInflater.from(context).inflate(R.layout.view3, parent, false)); } case TYPE_HOLDER4: { return new Holder4(LayoutInflater.from(context).inflate(R.layout.view4, parent, false)); } case TYPE_HOLDER5: { return new Holder5(LayoutInflater.from(context).inflate(R.layout.view5, parent, false)); } case TYPE_HOLDER6: { return new Holder6(LayoutInflater.from(context).inflate(R.layout.view6, parent, false)); } default: throw new RuntimeException("Not support type" + viewType); } } }
  • 64. Annotation Processing @BindHolder(Holder1.class) @BindHolder(Holder2.class) @BindHolder(Holder3.class, R.layout.view3) @BindHolder(Holder4.class, R.layout.view4) public class MyAdapter extends MyAdapterHelper {} @BindLayout(R.layout.item_holder1) class ViewHolder1 extends RecyclerView.ViewHolder {} @BindLayout(R.layout.item_holder2) class ViewHolder2 extends RecyclerView.ViewHolder {} // https://github.com/Jintin/ComposeAdapter
  • 67. Q&A