注解
定義數(shù)據(jù)
companion object {
const val RESOUCES_ONE = 1;
const val RESOUCES_TWO = 2;
}
定義數(shù)據(jù)
@IntDef({MainActivity.RESOUCES_ONE,MainActivity.RESOUCES_TWO})
@Target({ElementType.FIELD,ElementType.PARAMETER})
@Retention(RetentionPolicy.SOURCE)
public @interface AnnotateValue {
}
輸入錯誤會提示
錯誤提示
下面解釋
@Target:注解的作用目標(biāo)
public enum ElementType {
/** Class, interface (including annotation type), or enum declaration */
TYPE,
/** Field declaration (includes enum constants) */
FIELD,
/** Method declaration */
METHOD,
/** Formal parameter declaration */
PARAMETER,
/** Constructor declaration */
CONSTRUCTOR,
/** Local variable declaration */
LOCAL_VARIABLE,
/** Annotation type declaration */
ANNOTATION_TYPE,
/** Package declaration */
PACKAGE,
/**
* Type parameter declaration
*
* @since 1.8
*/
TYPE_PARAMETER,
/**
* Use of a type
*
* @since 1.8
*/
TYPE_USE,
/**
* Module declaration.
*
* @since 9
*/
MODULE
}
參數(shù) | 原文 | 注解 |
---|---|---|
ElementType.TYPE | Class, interface (including annotation type), or enum declaration | 類、接口(包括注釋類型)或枚舉聲明 |
ElementType.FIELD | Field declaration (includes enum constants) | 字段聲明(包括枚舉常量) |
ElementType.METHOD | Method declaration | 方法聲明 |
ElementType.PARAMETER | Formal parameter declaration | 形式參數(shù)聲明 |
ElementType.CONSTRUCTOR | Constructor declaration | 構(gòu)造函數(shù)聲明 |
ElementType.LOCAL_VARIABLE | Local variable declaration | 局部變量聲明 |
ElementType.ANNOTATION_TYPE | Annotation type declaration | 注解類型聲明 |
ElementType.PACKAGE | Package declaration | 包裝聲明 |
ElementType.TYPE_PARAMETER | Type parameter declarationSince:1.8 | 類型參數(shù)聲明自從:1.8 |
ElementType.TYPE_USE | Use of a type Since:1.8 | 使用類型自從:1.8 |
ElementType.MODULE | Module declaration. Since:9 | 模塊聲明。自從:9 |
@Target(ElementType.TYPE)——接口、類、枚舉、注解
@Target(ElementType.FIELD)——字段、枚舉的常量
@Target(ElementType.METHOD)——方法
@Target(ElementType.PARAMETER)——方法參數(shù)
@Target(ElementType.CONSTRUCTOR) ——構(gòu)造函數(shù)
@Target(ElementType.LOCAL_VARIABLE)——局部變量
@Target(ElementType.ANNOTATION_TYPE)——注解
@Target(ElementType.PACKAGE)——包
@Retention:注解的保留位置
public enum RetentionPolicy {
/**
* Annotations are to be discarded by the compiler.
*/
SOURCE,
/**
* Annotations are to be recorded in the class file by the compiler
* but need not be retained by the VM at run time. This is the default
* behavior.
*/
CLASS,
/**
* Annotations are to be recorded in the class file by the compiler and
* retained by the VM at run time, so they may be read reflectively.
*
* @see java.lang.reflect.AnnotatedElement
*/
RUNTIME
}
參數(shù) | 原文 | 注解 |
---|---|---|
RetentionPolicy.SOURCE | Annotations are to be discarded by the compiler. | 注釋將被編譯器丟棄。 |
RetentionPolicy.CLASS | Annotations are to be recorded in the class file by the compiler but need not be retained by the VM at run time. This is the default behavior. | 注釋將由編譯器記錄在類文件中,但不需要在運行時由 VM 保留。 這是默認(rèn)行為。 |
RetentionPolicy.RUNTIME | Annotations are to be recorded in the class file by the compiler and retained by the VM at run time, so they may be read reflectively.See Also:reflect.AnnotatedElement | 注釋將由編譯器記錄在類文件中,并在運行時由 VM 保留,因此可以反射性地讀取它們。反射.AnnotatedElement |
RetentionPolicy.SOURCE:這種類型的Annotations只在源代碼級別保留,編譯時 就會被忽略,在class字節(jié)碼文件中不包含。
RetentionPolicy.CLASS:這種類型的Annotations編譯時被保留,默認(rèn)的保留策略,在class文件中存在,但JVM將會忽略,運行時無法獲得。
RetentionPolicy.RUNTIME:這種類型的Annotations將被JVM保留,所以他們能在運行時被JVM或其他使用反射機制的代碼所讀取和使用。
@Document:說明該注解將被包含在javadoc中
@Inherited:說明子類可以繼承父類中的該注解
總結(jié):
三個值中SOURCE < CLASS < RUNTIME,即CLASS包含了SOURCE,RUNTIME包含SOURCE、CLASS
反射
下面先看代碼
public static void injectView(Activity activity) {
//獲取class
Class<? extends Activity> cla = activity.getClass();
//獲取對應(yīng)class下所有屬性
Field[] fields = cla.getDeclaredFields();
for (Field field : fields) {
//判斷是否有我們注解
boolean isEsite = field.isAnnotationPresent(AnnotateFindView.class);
if (isEsite) {
AnnotateFindView annotation = field.getAnnotation(AnnotateFindView.class);
int idResource = annotation.value();
View view = activity.findViewById(idResource);
field.setAccessible(true);
try {
field.set(activity, view);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
結(jié)合注解就可以省略getIntent
//創(chuàng)建注解
@Target({ElementType.FIELD,ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface ActivityValue {
String value() default "";
}
//反射賦值
public static void injntActivity(Activity activity) {
Class<? extends Activity> cla = activity.getClass();
Intent intent = activity.getIntent();
Bundle extras = intent.getExtras();
if (extras == null) {
return;
}
Field[] fields = cla.getDeclaredFields();
for (Field field : fields) {
boolean isExsit = field.isAnnotationPresent(ActivityValue.class);
if (isExsit) {
ActivityValue annotation = field.getAnnotation(ActivityValue.class);
String key = TextUtils.isEmpty(annotation.value()) ? field.getName() : annotation.value();
Object obj = extras.get(key);
Class<?> type = field.getType().getComponentType();
if (field.getType().isArray() &&null!=type&& Parcelable.class.isAssignableFrom(type)) {
Object[] objs = (Object[]) obj;
Class<? extends Object[]> clas = (Class<? extends Object[]>) field.getType();
obj = Arrays.copyOf(objs, objs.length, clas);
}
field.setAccessible(true);
try {
field.set(activity, obj);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
//跳轉(zhuǎn)
mainActivity.btnStartIntent.setOnClickListener {
val vo = UserData().apply {
age = 2
name = "小馬哥"
cla = "一年級二班"
}
val intent = Intent(this, ContentActivity::class.java).apply {
putExtra("name", "小明")
putExtra("age", 1)
putExtra("vo", vo)
}
startActivity(intent)
}
在跳轉(zhuǎn)的ContentActivity 注解以下就可以了
@ActivityValue
var name: String? = null;
@ActivityValue
var age: Int? = null;
@ActivityValue(value = "vo")
var dataVo: UserData? = null;
結(jié)合上面就可以擴展個別控件設(shè)置背景