元注解
注解上的注解:表示朱姐可以用在Java中的任何元素上,诸如:包名,类名,方法名,参数名,成员变量名
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE)//元注解:注解上的注解
@Retention(RetentionPolicy.SOURCE)
@interface Barry {
String value() default "BarryLiu"
}
有默认值使用的时候可以不传参,但是如果没有默认值default,那么使用的时候必须传参,而且只有参数为value的时候可以直接传参数,如果参数不是value,比如是id,那么就得用key,value的形式传参,Barry(id = “BarryLiu”)
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
public @interface Barry {
// String value() default "BarryLiu"
String id()
}
@Barry(id = "BarryLiu")
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_second_acivity)
}
}
RetentionPolicy.SOURCE:标记的注解仅保留在源码级别中,并被编译器忽略
RetentionPolicy.CLASS:标记的注解在编译时由编译器保留,但JVM会忽略
RetentionPolicy.RUNTIME:标记的注解由JVM保留,因此运行时环境可以使用它…结合反射来获取
SOURCE<CLASS<RUNTIME
APT:注解处理器(源码级别)怎么运行?
.java —>javac–>.class
采集到所有的注解信息–>Element–>注解处理程序
IntDef:源注解的作用:进行类型提示,语法检查
字节码:字节码增强
运行时:反射:动态获取注解与其元素(动态语言)
反射:通过类对对象进行操作
//手写类似于ButterKnife的控件id注入
import androidx.annotation.IdRes;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface injectView {
@IdRes int value()
}
public class injectUtil {
public static void injectView(Activity activity) {
Class<? extends Activity> aClass = activity.getClass();
//Field:获得自己+父类的成员,不包括private
//DeclaredField:获得自己的成员,不包括父类
//获得此类所有的成员
Field[] declaredFields = aClass.getDeclaredFields();
for (int i = 0; i < declaredFields.length; i++) {
Field declaredField = declaredFields[i];
if (declaredField.isAnnotationPresent(injectView.class)) {
injectView annotation = declaredField.getAnnotation(injectView.class);
int id = annotation.value();
View view = activity.findViewById(id);
declaredField.setAccessible(true);
try {
declaredField.set(activity, view);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
}
class MainActivity : AppCompatActivity() {
@injectView(R.id.textViewA)
lateinit var textView: TextView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_second_acivity)
injectUtil.injectView(this)
textView.text = "xxxix"
}
}