java注解
定义: @interface
@Target(ElmentType.TYPE)
@Retention(RetentionPolicy.SOURCE)
public @interface A{
String value() default "a";
}
注解保留级别 SOURCE CLASS RUNTIME
SOURCE:单纯阅读使用(该注解仅仅是声明,只会在源代码中留存,编译时会被删除,无法在编译期间和运行时通过反射获取)
CLASS:单纯编译时使用(该注解会在.class字节码中,但是不需要由虚拟机在运行时保留)
RUNTIME:运行时需要反射使用(注解会被保留到运行时,可以通过反射获取)
SOURCE一般用于生成额外的辅助类 比如 Butterknife IDE语法检查
CLASS 字节码增强, 编译出Class后修改Class数据实现修改代码逻辑 比如 ARouter
RUNTIME 反射, 程序运行期间反射获取注释和元素
注解作用域
TYPE:作用在类/接口声明上
ANNOTATION_TYPE:作用在注解声明上,target就是这种类型的注解
FIELD:作用在属性上,比如类中的某个参数
METHOD:作用在类中方法上面
android APT
创建java-library
引用模块 annotationProcessor project(':aptlibrary')
创建类 extends AbstractProcessor
@SupportedAnnotationTypes("xx.xx.xx.注解类名")//指示注释处理器支持的注释类型的注释
public class LanceProcessor extends AbstractProcessor{
@Override
public boolean process(Set<? extends TypeElement> set,RoundEnvironment roundEnvironment){
Message messager = proccessingEnv.getMessager();
messager.printMessage(Diagnostic.Kind.NOTE,"打印日志");
return false;
}
}
IDE语法检查注解
public static final int A = 1;
public static final int B = 2;
@IntDef(A,B)
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.SOURCE)
@interface Select{}
public void fun(@Select int i){}
java反射
Filed 获取自己+父类(不包括private)
DeclaredFiled 只获取自己的成员
利用反射+注解来取代findViewById
public class InjectUtils{
public static void injectView(Activity activity){
Field[] declaredFields = cls.getDeclaredFields();
for(Field declaredField : declaredFields){
if(declaredField.isAnnotationPresent(InjectView.class)){
InjectView injectView = declaredField.getAnnotation(InjectView.class);
int id = injectView.value();
View view = activity.findViewById(id);
declaredField.setAccessible(true);
try{
declaredField.set(activity,view);
}catch(IllegalAccessException e){
e.printStackTrace();
}
}
}
}
}
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface InjectView{
@IdRes int value();
}
利用反射+注解来取代getIntent
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface InjectIntent {
String value() default "";
}
public class InjectIntentUtils {
public static void injectIntent(Activity activity){
Class<? extends Activity> activityClass = activity.getClass();
Intent intent = activity.getIntent();
Bundle extras = intent.getExtras();
if(extras == null){
return;
}
//反射获取类里面的所有成员变量
Field[] declaredFields = activityClass.getDeclaredFields();
for (Field field : declaredFields) {
if(field.isAnnotationPresent(InjectIntent.class)){
InjectIntent injectIntent = field.getAnnotation(InjectIntent.class);
String key = injectIntent.value();
if(TextUtils.isEmpty(key)){
key = field.getName();
}
if(extras.containsKey(key)){
Object obj = extras.get(key);
//如果传的参数是一个数组类型的
if(field.getType().isArray()){
//获取数组类型的type
Class<?> componentType = field.getType().getComponentType();
if(componentType == null){
return;
}
//如果该数组类型是Parcelable的
if(Parcelable.class.isAssignableFrom(componentType)){
Object[] objs = (Object[]) obj;
Object[] objects = Arrays.copyOf(objs,objs.length, (Class<? extends Object[]>) field.getType());
obj = objects;
}
}
field.setAccessible(true);
try {
field.set(activity,obj);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
}
}