annotation可以理解为一种修饰符,用来将一些元数据与程序的类,方法,成员变量等进行关联。
annotation其实是通过动态代理来实现的,其中的成员变量以map形式则存储在java常量池中具体可以参考这篇文章https://blog.csdn.net/lylwo317/article/details/52163304
在android中常见的annotation有@Override @Deprecated @SuppressWarning等
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}
在Override中,可以看到类的类型是@interface
ElementType.CONSTRUCTOR:
用于描述构造器ElementType.FIELD:
用于描述域ElementType.LOCAL_VARIABLE:
用于描述局部变量ElementType.METHOD:
用于描述方法ElementType.PACKAGE:
用于描述包ElementType.PARAMETER:
用于描述参数ElementType.TYPE:
用于描述类、接口(包括注解类型) 或enum声明
RetentionPolicy.SOURCE :
注解只保留在源码中,编译时会忽略RetentionPolicy.CLASS :
更高一级,编译时被编译器保留,但是运行时会被 JVM 忽略RetentionPolicy.RUNTIME :
最高级,运行时会被保留,可以被运行时访问
- 新建 ContentView类
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface ContentView {
int value();
}
- 在activity中应用
@ContentView(R.layout.activity_main)
public class RuntimeAnnotionActivity extends AppCompatActivity {
@BindView(R.id.classAnnotion)
private Button btnGotoClassAnnotionActivity;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ContentViewInject.inject(RuntimeAnnotionActivity.this);
BindViewInject.inject(RuntimeAnnotionActivity.this);
btnGotoClassAnnotionActivity.setText("haha");
}
}
- 如何关联
public class ContentViewInject {
private ContentViewInject() {
}
public static void inject(Activity activity) {
// 找到使用 ContentView 注解的类
ContentView contentView = activity.getClass().getAnnotation(ContentView.class);
if (contentView != null) {
try {
activity.setContentView(contentView.value());
} catch (RuntimeException e) {
e.printStackTrace();
}
}
}
}
提供统一的静态方法注册,使用者不需要关心内部实现