注解反射 项目实战
- 前言
- 一、注解声明
- 二、反射实现
- 三、功能验证实现
- 总结
前言
实战需求通过自定义注解与反射实现页面跳转的参数注入:
- 页面跳转携带参数
- 使用注解标记属性参数
- 通过反射读取打印数据
一、注解声明
注解(Annotation),也叫元数据。一种代码级别的说明。它是JDK1.5及以后版本引入的一个特性,与类、接口、枚举是在同一个层次。它可以声明在包、类、字段、方法、局部变量、方法参数等的前面,用来对这些元素进行说明,注释。
在文章开始之前,我们先来写一个注解接口:
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Autowired {
String value() default "";
}
用@Target
注解标记另一个注解,以限制可以应用注解的Java 元素类型,Target 总共有八个元素类型。@Retention
注解指定标记注解的存储方式有三种类型,有兴趣的可以看我另一篇文章java 中的反射注解,进行学习了解,这里我就不再赘述了。
@Target(ElementType.FIELD)
: 允许在类与类属性上标记该注解。@Retention(RetentionPolicy.RUNTIME)
:标记的注解由JVM保留,因此运行时环境可以使用它。
二、反射实现
在贴源码之前,我们先来看一下接下来我们需要使用到的一些方法:
- getClass(): 获取当前上下文中的所有类。
- getIntent():获取当前上下文中的所有数据。
- getDeclaredFields():获取当前class 中的所有成员变量。
- getAnnotation():获取当前上下文中的注解。
- extras.get(key):获取当前 key 传入的数据。
接下我们直接创建一个反射 InjectUtils 工具类:
public class InjectUtils {
public static void InjectAutowired(Activity activity) {
// 获取当前所有的类
Class<? extends Activity> aClass = activity.getClass();
// 获取数据
Intent intent = activity.getIntent();
Bundle extras = intent.getExtras();
if (extras == null) {
return;
}
// 获取此类的所有成员
Field[] declaredFields = aClass.getDeclaredFields();
for (Field field : declaredFields) {
if (field.isAnnotationPresent(Autowired.class)) {
Autowired autowired = field.getAnnotation(Autowired.class);
// 获取当前key
String key = TextUtils.isEmpty(autowired.value()) ? field.getName() : autowired.value();
if (extras.containsKey(key)) {
Object obj = extras.get(key);
// 获取单个数组元素
Class<?> componentType = field.getType().getComponentType();
// 当前属性是数组并且是 Parcelable(子类)数组
if (field.getType().isArray() && Parcelable.class.isAssignableFrom(componentType)) {
Object[] objs = (Object[]) obj;
// 创建对应类型的数组,objs 拷贝
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();
}
}
}
}
}
}
文章代码并不多,结合我上面的注释及上面的一些主要方法的讲解,应该非常容易懂的哦。
三、功能验证实现
首先我们先创建一个 Activity 并实现数据的传参及跳转功能:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void onClick(View view) {
Intent intent = new Intent(this, MainActivity2.class);
intent.putExtra("name", "tiger");
startActivity(intent);
}
}
在 Activity2 中调用反射工具类,并通过注解的方式,打印输出属性变量:
public class MainActivity2 extends AppCompatActivity {
@Autowired
String name;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
InjectUtils.InjectAutowired(this);
System.out.println(name);
}
}
到这里,本篇文章就已经结束了,接下来我们来运行查看一下结果:
点击模拟器中的按钮,进去界面跳转,内容输入如下:
总结
本篇文章,使用自定义注解实战的方式,为大家带来更直观的学习理解,或许没有那么多的文字,但是我将详细的讲解实战示例中注解、反射中的使用说明,看到这里,我想你也应该学会了,感谢你的支持。
相关文章
暂无评论...