Infinum Android Talks #02 - How to write an annotation processor in Android
-
Upload
infinum-ltd -
Category
Technology
-
view
1.371 -
download
0
description
Transcript of Infinum Android Talks #02 - How to write an annotation processor in Android
How to writean annotation processor
in AndroidIvan Kušt
• Generics http://docs.oracle.com/javase/tutorial/java/generics/
• Reflectionhttp://docs.oracle.com/javase/tutorial/reflect/
• Annotationshttp://docs.oracle.com/javase/1.5.0/docs/guide/apt/mirror/overview-summary.html
How to write code faster?
Let’s look at our options
Generics Reflection Annotations
Speed Fast Slow Fast (if using compile time)
Ease of use Easy Medium Advanced
“Freedom" - generic types - modify everything at run-time
- generate code during compile
• use generics for type agnostic structures when possible (e.g. lists) - it’s easy and fast
• when that isn’t enough, use annotation processing - generate code that is boring to write
• generated code isn’t “visible” - use reflection to access it at run time from the code that you write
Approach
Let’s get our hands dirty• actually only the keyboard gets dirty over time
• prerequisites:- Android Studio (tested on version 0.4.0)- enable annotation processing(Open preference and navigate to Compiler → Annotation Processors. Check "Enable annotation processing”)- apt plugin https://bitbucket.org/hvisser/android-apt
• what is an annotation processor made of?- definition of annotations using @interface- a class that extends AbstractProcessor- entry containing processor name in META-INF/services/javax.annotation.processing.Processor
Project structure
• API project - annotation definitions - other non-generated code
• Compiler project- annotation processor implementation- annotation definitions (from API project) on classpath
• Application project - android application project- references to API and Compiler projects
API project
• android library project
• contains annotation definitions, for example:
Compiler project
• standard java library project- this is required in order to see APT classes
• API project sources must be in classpath (build.gradle):
Compiler project• AbstractProcessor implementation
- override process(…) method- return true if processing was successfull- add following annotations to processor class: @SupportedAnnotationTypes(“your.package.AnnotationName”)@SupportedSourceVersion(SourceVersion.RELEASE_7)
• create file: src/main/resources/META-INF/services/javax.annotation.processing.Processor
• add fully qualified class name of your processor class to the file (e.g. co.infinum.annotations.processor.TestProcessor)
Application project
• referencing API and Compiler projects in build.gradle:
Butterknife library
• UI dependency injection library
• View injection on Activities or arbitrary objects- no more writing findViewById(…)
• simplifying view holder pattern
• on click listener injection
View injection
class ExampleActivity extends Activity { @InjectView(R.id.title) TextView title; @InjectView(R.id.subtitle) TextView subtitle; @InjectView(R.id.footer) TextView footer;! @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.simple_activity); ButterKnife.inject(this); // TODO Use "injected" views... }}
• use @InjectView on fields representing view elements- fields can’t be private or protected
• call ButterKnife.inject(this) in onCreate()
Resources• annotations example:
https://github.com/ikust/hello-annotations
• http://turbomanage.wordpress.com/2012/09/28/annotation-processor-android-eclipse/
• https://bitbucket.org/hvisser/android-apt
• http://www.javacodegeeks.com/2012/11/java-annotations-tutorial-with-custom-annotation.html
• http://blog.retep.org/2009/02/13/getting-class-values-from-annotations-in-an-annotationprocessor/
• http://jakewharton.github.io/butterknife/