前言#
反射和注解的基本知识我们都已经了解了,这一篇来具体看看他俩如何结合使用,离我们的最终目标越来越近了。
正文#
现在来写一个通过注解来实现setContentView()的功能的Demo。
首先我们需要自定义一个注解,我们命名为ContentView:
package com.lzp.annotationstudy;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Created by li.zhipeng on 2017/3/9.
*
* 注解测试类
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface ContentView {
int value();
}
ContentView注解用来注解某一个类(TYPE),在运行时可以通过反射获取到具体的信息。value()之前介绍过,如果注解只有一个属性,系统推荐用value,注解中的值会以键值对的形式保存,就是属性的名称对应自身的值,而系统默认是value就是其中的一个键,这样的好处之后会看到。
定义好注解,现在就要通过反射来实现具体的功能了:
package com.lzp.annotationstudy;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* Created by li.zhipeng on 2017/3/9.
*
* 注解工具类
*/
public class AnnotationUtils {
public static void injectObject(Object handler){
// 拿到参数的Class类型
Class<?> handleType = handler.getClass();
// 获取Class类型上的ContentView注解
ContentView contentView = handleType.getAnnotation(ContentView.class);
if (contentView != null){
try {
// 通过反射找到Class类型中的setContentView(int param)方法
Method setContentViewMethod = handleType.getMethod("setContentView", int.class);
// 调用setContentView(int param),第一个是操作的对象,第二个是方法的参数
setContentViewMethod.invoke(handler, contentView.value());
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
代码中已经有很详细的注释了,接下来看看MainActivity中的代码:
package com.lzp.annotationstudy;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
//@ContentView(value = R.layout.activity_main)
@ContentView(R.layout.activity_main)
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
AnnotationUtils.injectObject(this);
}
}
这里看到了推荐使用value的好处,因为名称默认是value,所以我们就不需要写“value = ”了,如果是其他的名称,例如name之类的,就必须要写了。
看一下运行效果:
ok!!!
总结#
到这里所有的基础部分就都已经结束了,demo中反射了类的方法, 反射属性也大同小异,没什么太大的差别,下一篇直奔主题:自定义屌爆了的数据库框架。