infinum android talks #02 - how to write an annotation processor in android

13
How to write an annotation processor in Android Ivan Kušt

Upload: infinum-ltd

Post on 06-Jul-2015

1.371 views

Category:

Technology


0 download

DESCRIPTION

How to write your own annotation processor in Android Studio. Compile time and runtime annotations will be compared to reflection. To conclude, butterknife library will be presented as an example of using compile time annotation processing.

TRANSCRIPT

Page 1: Infinum Android Talks #02 - How to write an annotation processor in Android

How to writean annotation processor

in AndroidIvan Kušt

Page 2: Infinum Android Talks #02 - How to write an annotation processor in Android

• 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?

Page 3: Infinum Android Talks #02 - How to write an annotation processor in Android

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

Page 4: Infinum Android Talks #02 - How to write an annotation processor in Android

• 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

Page 5: Infinum Android Talks #02 - How to write an annotation processor in Android

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

Page 6: Infinum Android Talks #02 - How to write an annotation processor in Android

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

Page 7: Infinum Android Talks #02 - How to write an annotation processor in Android

API project

• android library project

• contains annotation definitions, for example:

Page 8: Infinum Android Talks #02 - How to write an annotation processor in Android

Compiler project

• standard java library project- this is required in order to see APT classes

• API project sources must be in classpath (build.gradle):

Page 9: Infinum Android Talks #02 - How to write an annotation processor in Android

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)

Page 10: Infinum Android Talks #02 - How to write an annotation processor in Android

Application project

• referencing API and Compiler projects in build.gradle:

Page 11: Infinum Android Talks #02 - How to write an annotation processor in Android

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

Page 12: Infinum Android Talks #02 - How to write an annotation processor in Android

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()

Page 13: Infinum Android Talks #02 - How to write an annotation processor in Android

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/