In the last blog post, I briefly introduced the basic use of Android Annotations, and also talked about the concept of contract programming. It seems that not many people are interested in it. Today, I will introduce a few slightly advanced uses of Android Annotations.

The ones I’m going to introduce may not be very common, but they are guaranteed to be

  • Thread Annotations
  • CheckResult Annotations
  • CallSuper Annotations
  • Enumerated Annotations

Thread Annotations

Annotations Thread Annotations have four members, @uithRead, @mainThread, @workerThread, @BinderThread, from different Java files, but share the same target.

@Retention(CLASS)
@Target({METHOD,CONSTRUCTOR,TYPE})Copy the code

If class is marked, all methods of that class must be executed on the specified thread, for example

@UiThread
public class NavigationBar {
  @NonNull
  private NavigationBar addEntry(
    @StringRes int iconFontRes, 
    @NonNull String title,
    @NonNull OnClickListener listener) {
    
  }
  
}Copy the code

All NavigationBar methods need to run on the Ui Thread, or Android Studio will! To quote! Wrong!

Annotations (@mainThread, @UithRead, @mainThread); To sum up: @MainThread is used to mark life-cycle related methods, and @UithRead is used for View Hierarchy, but Android Studio considers the two to be interchangeable, so methods with both tags can call each other.

And then I’ll add a little bit:

A process has only one MainThread, @mainthread, which is also an @uithread. For example, the activity’s main window runs on @MainThread, but the system also allows applications to create threads to run different Windows (there are few scenarios other than system processes doing this).

@CheckResult

This Annotation is especially useful for methods that don’t return a value just by looking at the method name, for example:

public boolean openUp()Copy the code

If you just look at the name of the method openUp, you probably won’t think twice about calling it, and you won’t judge the return value. But if you have to determine the openUp return value, there seems to be no other way to do it than with the document constraint. With @checkResults, things are straightforward.

@CallSuper

What if you provide an API for someone else to use, but the API must first call a superclass method to execute correctly? Let @callsuper save you.

Enumerated Annotations

Write high performance code, starting with no enum!

Each enum is an object, and none of the primitive type variables are as efficient in terms of memory or performance.

For example, if you define a class – ActionBar, you can use setMode to set different modes. If you use enum, it might look like this:

public class ActionBar { public enum Theme { DARK, LIGHT } private Theme mTheme; public void setTheme(Theme theme) { mTheme = theme; }}Copy the code

To improve code efficiency, you can replace Theme with two plastic variables, but this does not guarantee the validity of the Theme argument, and the user may pass in values other than DARK and LIGHT.

public class ActionBar { public static final int DARK = 0x00; public static final int LIGHT = 0x01; private int mTheme; public void setTheme(int theme) { mTheme = theme; }}Copy the code

How can we improve efficiency while ensuring the validity of the incoming parameters? I’ll just add a constraint with @intdef.

public class ActionBar { @IntDef({DARK, LIGHT}) @Retention(RetentionPolicy.SOURCE) public @interface Theme {} public static final int DARK = 0x00; public static final int LIGHT = 0x01; private int mTheme; public void setTheme(@Theme int theme) { mTheme = theme; } @Theme public int getTheme() { return mTheme; }}Copy the code

If the user calls setTheme with an invalid parameter, Android Studio will! To quote! Wrong!

If we want to make DARK and LIGHT a flag, allowing the user to combine them logically, we can call the setTheme like this.

setTheme(DARK | LIGHT);
setTheme(DARK & LIGHT);Copy the code

Just set @intdef’s flag property to true.

public class ActionBar { @IntDef(flag = true, value = {DARK, LIGHT}) @Retention(RetentionPolicy.SOURCE) public @interface Theme {} public static final int DARK = 0x00; public static final int LIGHT = 0x01; private int mTheme; public void setTheme(@Theme int theme) { mTheme = theme; } @Theme public int getTheme() { return mTheme; }}Copy the code

@stringdef works in the same way as @intdef except that the constants used are strings.

The resources

Copyright notice: This article is the blogger’s original article, shall not be reproduced without the permission of the blogger.