![](https://img.haomeiwen.com/i11345863/09245cb3a4d26c49.png)
..
最近在看大神的源码,发现有很多使用注解的地方,调查下相关的使用原理记录一下。_
注解
Java 注解(Annotation)又称 Java 标注,是 JDK5.0 引入的一种注释机制。
Java 语言中的类、方法、变量、参数和包等都可以被标注。
和 Javadoc 不同,Java 标注可以通过反射获取标注内容。在编译器生成类文件时,标注可以被嵌入到字节码中。Java 虚拟机可以保留标注内容,在运行时可以获取到标注内容 。
例如:
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}
元注解
元注解,专职负责注解其他的注解。
元注解 | 说明 | 取值 |
---|---|---|
@Target | 表示该注解可以用在什么地方 | ElementType.ANNOTATION_TYPE 可以应用于注释类型。ElementType.CONSTRUCTOR 可以应用于构造函数。ElementType.FIELD 可以应用于字段或属性。ElementType.LOCAL_VARIABLE 可以应用于局部变量。ElementType.METHOD 可以应用于方法级注释。ElementType.PACKAGE 可以应用于包声明。ElementType.PARAMETER 可以应用于方法的参数。ElementType.TYPE 可以应用于类的任何元素。 |
@Retention | 表示需要在什么级别保存该注解信息 | 1.SOURCE:在源文件中有效(即源文件保留)2.CLASS:在class文件中有效(即class保留)3.RUNTIME:在运行时有效(即运行时保留) |
@Documented | 表示将此注解包含在Javadoc中 | 无 |
@Inherited | 表示允许子类继承父类中的注解 | 无 |
Android注解
本来在Android系统源码中/frameworks/base/core/java/android/annotation中是有很多的注解的,但是,他们都是系统源码用的注解,不是给我们这种开发人员用的,因为所有的注解的注释上都有@hide注释。
/*
* {@hide}
*/
@Documented
@Retention(SOURCE)
@Target({METHOD, PARAMETER, FIELD})
public @interface AnyRes {
}
Android系统提供的SDK中,只有两个原生注解。位于android.annotation包中:
- @TargetApi 使高版本API的代码在低版本SDK不报错。
- @SuppressLint 使用此标注让Lint忽略指定的警告。
自定义注解
首先自定义注解InjectDIYLayout , 这里为了简单示例用了运行时注解,并采用反射方法调用执行。
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface InjectDIYLayout {
int value();
}
所有的注解类型都继承自这个普通的接口(Annotation)
实现工具类,在BaseActivity中的onCreate中初始化。InjectDIYUtils .inject(this);
public class InjectDIYUtils {
private static final String TAG = "InjectDIYUtils";
public static void inject(Object context){
injectDIYLayout (context);
}
}
通过类getAnnotation得到此类注释的注解,经打印可以判断是否此注解。然后通过反射获取到setContentView,并用反射方法的invoke调用,传入注解中的layout值。
private static void injectDIYLayout (Object context) {
Class<?> aClass = context.getClass();
InjectDIYLayout annotation = aClass.getAnnotation(InjectDIYLayout.class);
Log.e(TAG, "injectLayout: annotation.value()="+annotation.value());
try {
Method contentView = aClass.getMethod("setContentView", int.class);
try {
Object invoke = contentView.invoke(context, annotation.value());
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
使用举例:
@InjectDIYLayout(R.layout.activity_main)
public class MainActivity extends BaseActivity {
网友评论