390 likes | 558 Views
Android Annotations. Dale King. Goal. Give an overview of AndroidAnnotations to whet your appetite I’ll touch on probably 90% of the annotations My goal is not to make you an expert on AndroidAnnotations , but just make you want to go try it and learn more. What are AndroidAnnotations?.
E N D
Android Annotations Dale King
Goal • Give an overview of AndroidAnnotations to whet your appetite • I’ll touch on probably 90% of the annotations • My goal is not to make you an expert on AndroidAnnotations, but just make you want to go try it and learn more.
What are AndroidAnnotations? • AndroidAnnotations is an Open Source annotation processing library that speeds up Android development • It takes care of the plumbing, and lets you concentrate on what's really important. • By simplifying your code, it facilitates its maintenance. "The ratio of time spent reading [code] versus writing is well over 10 to 1... making it easy to read makes it easier to write." - Robert C. Martin
What is Annotation Processing? • Annotation Processing is a feature of the Java compiler that lets you write a library to process source code annotations at compile time • Runs your annotation processing code in the compiler and can generate new source code files that will also be compiled • There is no way with public API to modify existing classes
How does it work? • AndroidAnnotations is a Java Annotation Processing Tool that generates Android specific source code based on annotations • It enhances a class by subclassing it with a generated class that adds and overrides methods in the annotated class • The generated class is named by appending an underscore to the name of the annotated class
How do you use it? • APT is built into Sun javac so all you have to do is include Android Annotations jar in compile time class path • In Eclipse it needs to be enabled for the project • There is a bug in the Eclipse compiler that causes spurious errors if you import an APT generated class. So either access from same package or fully qualify
How do you use it? • Everywhere in the project that you refer to an enhanced class you append an underscore to the class name: • In the Android Manifest • In layout resources • In the code • The git repo has examples on setting up with maven + eclipse and gradle
Enhanced Component Annotations • Code generation begins with a class that is annotated with one of the enhanced component annotations (which start with E) • @EActivity • @EApplication • @EBean • @EFragment • @EProvider • @EReceiver • @EService • @EView • @EViewGroup
Layout Injection With @EActivity and @EFragment public class MyListActivity extends ListActivity { @Override public void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.main); } @EActivity(R.layout.main) public class MyListActivity extends ListActivity {
Fluent Intent Building Interface for EActivity and EService Intent intent = new Intent(myContext, MyActivity.class);intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TOP);startActivity(intent); MyActivity_.intent(myContext) .flags(Intent.FLAG_ACTIVITY_NEW_TOP) .start();
View Injections • For components with associated views you can have views automatically injected into fields @EActivity publicclassMyActivityextends Activity { // Injects R.id.myEditText @ViewByIdEditTextmyEditText; @ViewById(R.id.myTextView) TextViewtextView;
Resource Injections • Can have resources automatically injected into fields. 16 different annotations based on type: @Eactivity publicclassMyActivityextends Activity { @StringRes(R.string.hello) String myHelloString; @IntegerResint offset;
@EApplication and @App • EApplication adds no new functionality to annotated application but let’s you automatically inject the application into any other enhanced component using @App annotation: @EActivity publicclassMyActivityextendsActivity { @App MyApplicationapplication;
@EBean and @Bean • EBean lets you enable enhancement for your own custom classes. Class must have one constructor that takes no parameters or a Context parameter. • You can automatically inject new instances of a bean into any other enhanced component using @Bean annotation: • Optionally EBean can be declared as a singleton
Injecting Beans @EActivity publicclassMyActivityextends Activity { @Bean MyBeanmyEnhancedBean; @Bean(MyImplementation.class) MyInterfacemyInterface;
@Extra • @Extra lets you inject extra values from an intent into an EActivity @EActivity publicclassMyActivityextends Activity { @Extra("myStringExtra") String myMessage; @Extra Date myDate = new Date();
Fragment Injection • Lets you inject fragments by ID or by tag • Does not create them, must already be created (e.g. in the layout) @EActivity(R.layout.fragments) publicclassMyActivityextendsFragmentActivity{ @FragmentByIdMyFragmentmyFragment; @FragmentByTag("myFragmentTag") MyFragmentmyFragmentTag2;
Fragment Argument Injection • Lets you inject arguments to a fragment into an enhanced fragment: @EFragment publicclassMyFragmentextends Fragment { @FragmentArg("myStringArgument") String myMessage; @FragmentArg String anotherStringArgument;
System Service Injection • Simplifies accessing system services from an activity: NotificationManagernotificationManager= (NotificationManager)context.getSystemService( Context.NOTIFICATION_SERVICE); @EActivity publicclassMyActivityextends Activity { @SystemService NotificationManagernotificationManager;
@AfterViews • Method annotation for methods that are called after views are injected: @EActivity(R.layout.main) publicclassMyActivityextends Activity { @ViewByIdTextViewmyTextView; @AfterViewsvoidupdateTextWithDate(){ myTextView.setText("Date: " +new Date()); }
@AfterInject • Method annotation for methods to be called when injection is complete for @Ebean @EBeanpublicclassMyClass{ @Bean MyOtherClassdependency; publicMyClass(){ // dependency is null } @AfterInjectpublicvoiddoSomething (){ // dependency is set here }
Event Binding • Method annotations for methods that are automatically called in response to UI events @TextChange @AfterTextChange @BeforeTextChange @FocusChange @CheckedChange @Touch @Click @LongClick @ItemClick @ItemLongClick @ItemSelect @OptionsItem @SeekBarProgressChange @SeekBarTouchStart @SeekBarTouchStop
Event Binding Examples @Click(R.id.myButton) voidmyButtonWasClicked(){[...]} @Click voidanotherButton(){... } @Click voidyetAnotherButton(View clickedView){... }
@Background Annotation • Method annotation that causes method to be executed on a background thread voidmyMethod(){ someBackgroundWork("hello", 42); } @Background voidsomeBackgroundWork(String aParam,longanotherParam) { // … }
@Background parameters • @Background(id="cancelable_task") • Allows job to be cancelled based on id • @Background(serial = "test") • All background tasks with same serial value will be executed sequentially • @Background(delay=2000) • Delay before starting task
@UIThread • Method annotation that causes method to run on UI Thread (supports delay parameter): voidmyMethod(){ doInUiThread("hello", 42); } @UiThread voiddoInUiThread(String aParam,longanotherParam){ // ... }
EActivity Modification annotations • Annotations to add to an EActivity to modify its behavior • @NoTitle • Shows activity with no title • @FullScreen • Requests full screen • @CustomTitle(R.layout.custom_title) • Use custom resource for title
Shared Preference Annotations • Annotations to create a type-safe shared preference interface: @SharedPref publicinterfaceMyPrefs{ @DefaultString("John") String name(); @DefaultInt(42) intage(); longlastUpdated(); }
Injecting Shared Preference • The @Pref annotation will inject a shared preference instance: @EActivity publicclassMyActivityextends Activity { @Pref MyPrefs_ myPrefs; // ... }
Modifying Shared preferences // Simple edit myPrefs.name().put("John"); // Batch edit myPrefs.edit().name().put("John") .age().put(42).apply(); // Preference clearing: myPrefs.clear();
Reading Shared Preferences // Check if a value exists: booleannameExists= myPrefs.name().exists(); // Reading a value longlastUpdated=myPrefs.lastUpdated().get(); // Reading a value and providing a default longnow =System.currentTimeMillis(); longlastUpdated=myPrefs.lastUpdated().getOr(now);
Options Menu annotations @EActivity @OptionsMenu(R.menu.my_menu) publicclassMyActivityextends Activity { @OptionMenuItem MenuItemmenuSearch; @OptionsItem(R.id.menuShare) voidmyMethod(){ // … }
Options Menu continued @OptionsItem voidhomeSelected(){ // The "Selected" keyword is optional }@OptionsItem({R.id.menu_search, R.id.menu_delete}) voidmultipleMenuItems(){ } @OptionsItemvoidmenu_add(MenuItem item){ // You can add a MenuItemparameter }
@InstanceState • Field annotation to cause field to be saved and restored in instance state automatically @Eactivity publicclassMyActivityextends Activity { @InstanceState intsomeId; @InstanceState MySerializableBeanbean;
@OnActivityResult • Method annotation to connect methods as callbacks for startActivityForResult @OnActivityResult(REQUEST_CODE) voidonResult(intresultCode, Intent data){}@OnActivityResult(REQUEST_CODE) voidonResult(intresultCode){} @OnActivityResult(ANOTHER_REQUEST_CODE) voidonResult(Intent data){} @OnActivityResult(ANOTHER_REQUEST_CODE) voidonResult(){}
Miscellaneous • @OrmLiteDao – Field annotation for injecting OrmLite DAOs • @RoboGuice – Combine Android Annotations with RoboGuice dependency injection without subclassing • @Trace – Method annotation that logs entry and exit for the method • @Transactional – Method annotation that executes method in a SQLite transaction
REST API • Rest API lets you easily create REST clients using clean interfaces. • It is a wrapper around the Spring Android RestTemplate Module.
Summary • Android Annotations lets you reduce the amount of code to create an Android app • Takes care of the boilerplate code for you. • The work is done at compile time so does not slow app down (unlike RoboGuice) • https://github.com/excilys/androidannotations