Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Annotation Processing Tools - Droidcon Madrid 2015
Search
Rubén Serrano
April 25, 2015
Programming
180
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Annotation Processing Tools - Droidcon Madrid 2015
Rubén Serrano
April 25, 2015
More Decks by Rubén Serrano
See All by Rubén Serrano
Clean Architecture the Right Way. Or almost...
akelael
3
240
Flutter, the road to Fuchsia (DevFest Tarragona 2018)
akelael
0
91
Architecting the Redbooth Android App - GDG Barcelona Android Community Day
akelael
2
180
Unclean Architecture in Android - Droidcon Madrid 2016
akelael
0
110
From Legacy to Hexagonal (Codemotion Madrid 2014)
akelael
5
380
Evolución Android (v3.0, DevFest Tarragona 2014)
akelael
0
60
From Legacy to Hexagonal Android (Droidcon London 2014)
akelael
1
180
Evolución Android
akelael
0
140
Other Decks in Programming
See All in Programming
言葉の格闘技のススメ~紙とペンと言葉から始める、キャリアの描き方~
progresscicada
2
170
いまどきの Codex で開発する visionOS アプリの開発スタイルについて
karad
0
160
AI Readyの正体はデータマネジメントだ メダリオン2.0の最前線
freee
PRO
0
360
複数の Claude Code が"放置"されてしまう問題をCLI ダッシュボードを自作して解決した話
sumihiro3
1
720
Press start. Python's next generation.
willingc
PRO
2
110
Pythonの実行はどこまで賢くなったのか? CPythonとPyPyから見る最適化のしくみ
curekoshimizu
3
1.7k
TSX の <Hoge<Fuga>> という構文に驚いた話 / tsx-type-argument-syntax
kanaru0928
0
240
わからない話を追いかけたら、プログラミング言語を作る側にいた
ydah
3
540
リアルな遅延を測る仕様
kota_yata
1
120
Loosening the Reins: Go Generics Get More Flexible
kuro_kurorrr
0
290
不幸な GC
chencmd
0
640
My Marp Sample
sinoue0108
0
110
Featured
See All Featured
Music & Morning Musume
bryan
47
7.3k
Pawsitive SEO: Lessons from My Dog (and Many Mistakes) on Thriving as a Consultant in the Age of AI
davidcarrasco
0
220
Unlocking the hidden potential of vector embeddings in international SEO
frankvandijk
0
900
Money Talks: Using Revenue to Get Sh*t Done
nikkihalliwell
0
470
Java REST API Framework Comparison - PWX 2021
mraible
34
9.7k
Measuring Dark Social's Impact On Conversion and Attribution
stephenakadiri
2
260
Automating Front-end Workflow
addyosmani
1369
210k
What Being in a Rock Band Can Teach Us About Real World SEO
427marketing
0
1.1k
The Cult of Friendly URLs
andyhume
79
7k
Art, The Web, and Tiny UX
lynnandtonic
304
22k
Speed Design
sergeychernyshev
33
2k
The Curious Case for Waylosing
cassininazir
1
480
Transcript
Annotation Processing Tools 101
Txus Ballesteros @txusballesteros Rubén Serrano @akelael
Agenda 1. Annotation Processing Tool 2. Discusión 3. Caso práctico
¿Qué es eso de APT?
public @interface DummyAnnotiation {} Anotación
Retención • Constructor • Atributo • Variable • Método •
Parámetro • Etc. • Source • Class • Runtime Objetivo
Anotación @Retention(CLASS) @Target(FIELD) public @interface InjectView { int value(); }
Runtime Class tiene la magia: • getAnnotation(Class<T> annotationType) • getAnnotations()
• getDeclaredAnnotations() • isAnnotationPresent(Class<T> annotationType)
Mirror API http://docs.oracle.com/javase/1.5.0/docs/guide/apt/mirror/overview-summary.html
Discusión
Caso Práctico
Android Transformer https://github.com/txusballesteros/android-transformer
Creando Anotaciones @Retention(RetentionPolicy.SOURCE) @Target(ElementType.TYPE) public @interface Mappable { Class<?>
with(); }
Creando Anotaciones @Retention(RetentionPolicy.SOURCE) @Target(ElementType.TYPE) public @interface Mappable { Class<?>
with(); }
Configurando las Anotaciones @Retention(RetentionPolicy.SOURCE) @Target(ElementType.TYPE) public @interface Mappable {
Class<?> with(); }
Configurando las Anotaciones @Retention(RetentionPolicy.SOURCE) @Target(ElementType.TYPE) public @interface Mappable {
Class<?> with(); }
@SupportedSourceVersion(SourceVersion.RELEASE_7) @SupportedAnnotationTypes({ "com.mobandme.android.transformer.compiler.Mapping", "com.mobandme.android.transformer.compiler.Mappable", "com.mobandme.android.transformer.compiler.Parse" }) public class AnnotationsProcessor extends
AbstractProcessor { RoundEnvironment roundEnvironment; Map<String, MapperInfo> mappersList; @Override public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { return true; } Creando el Procesador
@SupportedSourceVersion(SourceVersion.RELEASE_7) @SupportedAnnotationTypes({ "com.mobandme.android.transformer.compiler.Mapping", "com.mobandme.android.transformer.compiler.Mappable", "com.mobandme.android.transformer.compiler.Parse" }) public class AnnotationsProcessor extends
AbstractProcessor { RoundEnvironment roundEnvironment; Map<String, MapperInfo> mappersList; @Override public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { return true; } Creando el Procesador
@SupportedSourceVersion(SourceVersion.RELEASE_7) @SupportedAnnotationTypes({ "com.mobandme.android.transformer.compiler.Mapping", "com.mobandme.android.transformer.compiler.Mappable", "com.mobandme.android.transformer.compiler.Parse" }) public class AnnotationsProcessor extends
AbstractProcessor { RoundEnvironment roundEnvironment; Map<String, MapperInfo> mappersList; @Override public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { return true; } Configurando el Procesador
Implementando el Procesador @SupportedSourceVersion(SourceVersion.RELEASE_7) @SupportedAnnotationTypes({ "com.mobandme.android.transformer.compiler.Mapping", "com.mobandme.android.transformer.compiler.Mappable", "com.mobandme.android.transformer.compiler.Parse" }) public
class AnnotationsProcessor extends AbstractProcessor { RoundEnvironment roundEnvironment; Map<String, MapperInfo> mappersList; @Override public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { return true; }
Implementando el Procesador private void processMappedAnnotationElements() { Set<? extends Element>
elements = roundEnvironment.getElementsAnnotatedWith(Mapped.class); for (Element mappedElement : elements) { if (mappedElement.getKind() == ElementKind.FIELD) { Mapped mappedAnnotation = mappedElement.getAnnotation(Mapped.class); String toFieldName = mappedAnnotation.toField(); } } }
Implementando el Procesador private void processMappedAnnotationElements() { Set<? extends Element>
elements = roundEnvironment.getElementsAnnotatedWith(Mapped.class); for (Element mappedElement : elements) { if (mappedElement.getKind() == ElementKind.FIELD) { Mapped mappedAnnotation = mappedElement.getAnnotation(Mapped.class); String toFieldName = mappedAnnotation.toField(); } } }
Implementando el Procesador private void processMappedAnnotationElements() { Set<? extends Element>
elements = roundEnvironment.getElementsAnnotatedWith(Mapped.class); for (Element mappedElement : elements) { if (mappedElement.getKind() == ElementKind.FIELD) { Mapped mappedAnnotation = mappedElement.getAnnotation(Mapped.class); String toFieldName = mappedAnnotation.toField(); } } }
Implementando el Procesador private void processMappedAnnotationElements() { Set<? extends Element>
elements = roundEnvironment.getElementsAnnotatedWith(Mapped.class); for (Element mappedElement : elements) { if (mappedElement.getKind() == ElementKind.FIELD) { Mapped mappedAnnotation = mappedElement.getAnnotation(Mapped.class); String toFieldName = mappedAnnotation.toField(); } } }
Generando el Código JavaFileObject file = processingEnv.getFiler().createSourceFile(name); BufferedWriter buffer =
new BufferedWriter(file.openWriter()); //… buffer.close();
Configurando el Entorno com.mobandme.android.transformer.compiler.internal.AnnotationsProcessor
Configuración de Gradle para el Compilador buildscript { repositories {
maven { url "https://oss.sonatype.org/content/repositories/snapshots/" } jcenter() } dependencies { classpath 'com.jimdo.gradle:gradle-apt-plugin:0.5-SNAPSHOT' } } apply plugin: 'java' apply plugin: 'apt'
El resultado final
¿Preguntas?