- Annotations are widely used in Android development, and open source frameworks are also widely used. Although we have few custom annotations, we also need to understand the basic knowledge.
1. Definition of annotations
- Java annotations, also known as Java annotations, are an Annotation mechanism introduced in JDK5.0. Annotations are a form of metadata that provides information about
Data belonging to a program but not to the program itself. Annotations have no direct effect on the actions of the code they annotate.
2. What do annotations look like
- All annotations in Java implement the “Annotation” interface by default
package java.lang.annotation;
public interface Annotation {
boolean equals(Object obj);
int hashCode();
String toString();
Class<? extends Annotation> annotationType();
}
Copy the code
- The most common thing we see is an override annotation, which appears whenever a subclass overrides a method of its parent class.
- Look at the “@override” source code. The annotation is written as “@interface”. Does it look like an interface? “, but with an extra “@” symbol in front
- And this annotation has an annotation on it, which is a meta-annotation
3. Classification and functions of annotations
- I sorted out some here, write their own notes, not familiar with the page to see how long familiar with the use
4. Note writing
- If there is only one default parameter value, you can omit the parameter key =
// Where does it work: class, interface, method, attribute variable
@Target({ElementType.TYPE,ElementType.METHOD, ElementType.FIELD})
// The lifecycle is at run time
@Retention(RetentionPolicy.RUNTIME)
public @interface TestAnnotation {
// If you use value, you can use "value = 111", or you can write "111" directly.
int value(a);
}
@TestAnnotation(111)
private int num1;
@TestAnnotation(value = 111)
private int num2;
Copy the code
- If more than one argument is passed, “value = 111” must be written in full
- If there is a default parameter of “default”, you do not need to pass the parameter
- Default can also be passed to override the original value
// Where does it work: class, interface, method, attribute variable
@Target({ElementType.TYPE,ElementType.METHOD, ElementType.FIELD})
// The lifecycle is at run time
@Retention(RetentionPolicy.RUNTIME)
public @interface TestAnnotation {
// If you use value, you can use value = 111 or you can write 111 directly
int value(a);
// create a data1 parameter (value = 111, data1 = "111", value = "111")
String data1(a);
// If there is a default value, you can leave this parameter blank or add data2 = "222" to it
String data2(a) default "222";
}
@TestAnnotation(value = 111,data1 = "111")
private int num1;
@TestAnnotation(value = 111,data1 = "111",data2 = "333")
private int num2;
Copy the code
5. Use of annotations
5.1 Obsolete Marks
- Deprecated: Deprecated: Deprecated: Deprecated: Deprecated: Deprecated: Deprecated: Deprecated: Deprecated: Deprecated: Deprecated: Deprecated: Deprecated: Deprecated
[img-fe5wcaaq-1597598164260] [upload_images.jianshu. IO /upload_imag…]
5.2 Syntax Check
- The syntax checking annotation “@intdef”, which limits parameter types, can be used instead of enumeration types
- There are many more @drawableres, @idres, @stringres, @animres, and so on in Android
public class WeekDay {
public static final int MONDAY = 1;
public static final int TUESDAY = 2;
public static final int WEDNESDAY = 3;
// Valid at source stage for syntax verification
@Retention(RetentionPolicy.SOURCE)
// This annotation modifies attributes and method parameters
@Target({ElementType.FIELD, ElementType.PARAMETER})
// Only these types can be passed in
@IntDef({MONDAY, TUESDAY, WEDNESDAY})
public @interface WeekDayAnnotation {
}
}
Copy the code
- We can see that if we write 1, we get an error indicating only the type that can be passed
5.3 the findViewById
- Annotate the control without having to write findViewById repeatedly
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface InjectView {
@IdRes int value(a);
}
/ * -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - * /
public class InjectViewUtils {
public static void injectView(Activity activity) {
Class<? extends Activity> clazz = activity.getClass();
// Get the member
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
// Check whether the InjectView annotation tag is marked
if (field.isAnnotationPresent(InjectView.class)) {
InjectView injectView = field.getAnnotation(InjectView.class);
// Get the View id
int id = injectView.value();
View view = activity.findViewById(id);
// Reflection set value
// Set the permission to modify the properties of private
field.setAccessible(true);
try {
field.set(activity,view);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
}
Copy the code
- use
@InjectView(R.id.tvTest)
private TextView tvTest;
@InjectView(R.id.tvTest2)
private TextView tvTest2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
InjectViewUtils.injectView(this);
}
Copy the code
5.4 the View of the Onclick
- Don’t need to get the View, also don’t need to write the View Onclick listener, directly add annotations, save trouble
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface InjectOnClick {
@IdRes int[] value();
}
/ * -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - * /
/** * click event handler */
public class OnClickUtils {
static public void inject(final Activity activity) {
Class<? extends Activity> clazz = activity.getClass();
// Get all methods
Method[] methods = clazz.getDeclaredMethods();
for (final Method method : methods) {
// Determine the annotation type of the method
if (method.isAnnotationPresent(InjectOnClick.class)) {
InjectOnClick injectOnClick = method.getAnnotation(InjectOnClick.class);
// Get the id parameter array
int[] ids = injectOnClick.value();
// Set permission. Private can be changed
method.setAccessible(true);
for (int id : ids) {
// Set each id
activity.findViewById(id).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// Call the method back
try {
method.invoke(activity);
} catch (Exception e) {
e.printStackTrace();
try {
method.invoke(activity, v);
} catch(Exception ex) { ex.printStackTrace(); }}}}); } } } } }Copy the code
- use
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
OnClickUtils.inject(this);
}
@InjectOnClick({R.id.tvTest, R.id.tvTest2})
private void OnClick(View view) {
int id = view.getId();
if (id == R.id.tvTest) {
} else if (id == R.id.tvTest2) {
}
}
Copy the code
6. The ending
- Annotations are simple to use, but often need to work with reflection technology. If you learn more about annotations in the future, I will share with you.