手写findviewbyid和使用注解给变量赋值
使用到注解和反射
注解本身没有什么含义,只有配合反射和插桩技术时才能体现价值
我们平时要初始化view都需要调用findviewbyid,那我们可不可以省去这一步呢?答案当然是可以的,下面我们就一块看看具体是怎么实现的。
首先要了解注解和反射,不理解的小伙伴,去百度查一下,这里就不一一解释了
//findviewbyid 的注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AutoFindView {
@IdRes int value();
}
用于初始化,在setcontentview之后调用就可以了
public class InitView {
public static void init(Activity activity) throws IllegalAccessException {
Class<? extends Activity> aClass = activity.getClass();
Intent intent = activity.getIntent();
Bundle extras = intent.getExtras();
Field[] fields = aClass.getDeclaredFields();
for (Field field : fields) {
if (field.isAnnotationPresent(AutoFindView.class)){
View view = activity.findViewById(field.getAnnotation(AutoFindView.class).value());
field.setAccessible(true);
field.set(activity,view);
}
}
}
}
调用示例
@AutoFindView(R.id.editText)
private EditText editText;
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.a_layout);
try {
InitView.init(this);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
我们还可以利用反射+注解实现变量自动复制,比如当我们使用intent传值的时候
Intent intent = new Intent(this,BActivity.class);
intent.putExtra("name",editText.getText().toString());
startActivity(intent);
在BActivity中接收
@AutoValue
private String name;
private String TAG = getClass().getName();
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
try {
InitView.init(this);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
Log.e(TAG, "onCreate: name:"+name );
}
赋值的注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AutoValue {
String value() default "";
}
完整的InitView
public class InitView {
public static void init(Activity activity) throws IllegalAccessException {
Class<? extends Activity> aClass = activity.getClass();
Intent intent = activity.getIntent();
Bundle extras = intent.getExtras();
Field[] fields = aClass.getDeclaredFields();
for (Field field : fields) {
if (field.isAnnotationPresent(AutoValue.class)) {
Object o = extras.get(field.getName());
String autoValue = field.getAnnotation(AutoValue.class).value();
String key = TextUtils.isEmpty(autoValue)?field.getName():autoValue;
if (extras.keySet().contains(key)) {
Object o = extras.get(field.getName());
Class<?> componentType = field.getType().getComponentType();
//Parcelabled数组需要特殊处理一下
if (field.getType().isArray() && Parcelable.class.isAssignableFrom(componentType)) {
Object[] objects = (Object[]) o;
Object[] objects2 = Arrays.copyOf(objects, objects.length, (Class<? extends Object[]>) field.getType());
o = objects2;
}
if (o != null) {
field.setAccessible(true);
field.set(activity,o);
}
}
if (field.isAnnotationPresent(AutoFindView.class)){
View view = activity.findViewById(field.getAnnotation(AutoFindView.class).value());
field.setAccessible(true);
field.set(activity,view);
}
}
}
}