示例1:实现ButerKnife库的自动获取view
声明view的注解:
java
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface InjectView {
@IdRes int value(); //view id
}
在activity中获取注解value实现findViewById:
java
public class InjectUtil {
public static void injectView(Activity activity) {
Class<? extends Activity> aClass = activity.getClass();
Field[] declaredFields = aClass.getDeclaredFields();
for (Field field: declaredFields) {
if (field.isAnnotationPresent(InjectView.class)) { //如果该field含有InjectView类注解
InjectView annotation = field.getAnnotation(InjectView.class); //获取该注解类型对象
View view = activity.findViewById(annotation.value());
field.setAccessible(true);
try {
field.set(activity, view); //将该view设置给该属性对象
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
}
}
}
使用:
java
class MainActivity : ComponentActivity() {
@InjectView(R.id.btn_click)
private var button: Button ?= null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
InjectUtil.injectView(this)
}
示例2:实现ARouter库的autowire获取传递数据
Autowired注解:
java
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Autowired {
String value();
}
获取activity的intent,从带有Autowired注解的filed中获取intent的key,将对象设置给该filed。
java
public class InjectUtil {
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 annotation = field.getAnnotation(Autowired.class);
String key = TextUtils.isEmpty(annotation.value()) ? field.getName() : annotation.value(); //如果设置了value,key就是value,否则key就用name
if (!key.isEmpty()) {
Object obj = extras.get(key);
field.setAccessible(true);
try {
field.set(activity, obj);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
}
}
}
}
使用:
java
public class MainActivity2 extends ComponentActivity {
@Autowired("name")
String name;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
InjectUtil.injectAutowired(this);
setContentView(R.layout.activity_main2);
Toast.makeText(getApplicationContext(), "我的名字: " + name, Toast.LENGTH_LONG).show();
}
}
示例3:获取某个类某个方法的所有泛型和返回类型
Person类:
java
public class Person {
private String userName;
private String password;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public List<Person> method(List<Person> persons) {
return new ArrayList<>(persons);
}
}
java
public class ReflectionGeneric {
@RequiresApi(api = Build.VERSION_CODES.P)
public static void inject() throws NoSuchMethodException, ClassNotFoundException {
Method method = Person.class.getMethod("method", List.class);
Type[] genericParameterTypes = method.getGenericParameterTypes();
//获取泛型类型
for (Type genericParameterType : genericParameterTypes) {
//获取泛型里面的实际参数类型
Type[] actualTypeArguments = ((ParameterizedType) genericParameterType).getActualTypeArguments();
for (Type actualTypeArgument : actualTypeArguments) {
//获取非String类型的类
if (actualTypeArgument.getTypeName().equals("java.lang.String")) {
String classNamePath = actualTypeArgument.getTypeName();
Class<?> aClass = Class.forName(classNamePath);
//获得所有属性
Arrays.stream(aClass.getDeclaredFields()).forEach(System.out::println);
}
}
}
//获取返回类型
Type genericReturnType = method.getGenericReturnType();
Type[] actualTypeArguments = ((ParameterizedType) genericReturnType).getActualTypeArguments();
Type actualTypeArgument = actualTypeArguments[0];
if (actualTypeArgument.getTypeName().equals("java.lang.String")) {
//获取参数全类名
String classNamePath = actualTypeArgument.getTypeName();
//根据类路径获取class文件
Class<?> returnClass = Class.forName(classNamePath);
//获得所有属性
Arrays.stream(returnClass.getDeclaredFields()).forEach(System.out::println);
}
}
}
示例4:实现Hilt库的自动注入对象
单例对象注解和非单例对象注解:
java
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface SimpleInject {
}
@Target({ElementType.FIELD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface SimpleSingleInject {
}
java
/**
* 自动注入创建对象
*/
public class Hilt {
public static Map<Class<?>, Object> instances = new ConcurrentHashMap<>();
public static <T> T getSingleInstance(Class<T> cls) {
try {
//判断是否走单例
if (!cls.isAnnotationPresent(SimpleSingleInject.class)){
return getInstance(cls);
}
Object obj = instances.get(cls);
if (null != obj) {
return (T)obj;
}
//使用类锁锁代码块
synchronized (cls) {
if (null == instances.get(cls)) {
obj = getInstance(cls);
instances.put(cls, obj);
}
}
return (T)obj;
}
catch (Exception e) {
throw new RuntimeException();
}
}
public static<T> T getInstance (Class<T> cls){
//如果该class中含有SimpleInject注解的filed,则反射创建该filed对象设置给该class
try {
T obj = cls.newInstance();
//返回本类申明的字段包括非public,不包括父类
Field[] declaredFields = cls.getDeclaredFields();
for (Field f : declaredFields) {
//判断字段是否包含指定注解类型
if (f.isAnnotationPresent(SimpleInject.class)) {
//判断字段是否为私有
if (!f.isAccessible()) {
f.setAccessible(true);
}
//再次递归调用赋值
f.set(obj, getInstance(f.getType()));
}
}
return obj;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
提供注解对象的module:
java
public class Module {
@SimpleInject
Person person;
}
使用:
java
public class MainActivity3 extends ComponentActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
Module singleInstance = Hilt.getSingleInstance(Module.class);
singleInstance.person.setUserName("haha");
singleInstance.person.setPassword("123456");
Toast.makeText(getApplicationContext(), "我的名字: " + singleInstance.person.getUserName() + " 我的密码:" + singleInstance.person.getPassword(), Toast.LENGTH_LONG).show();
}
}
示例5:实现Retrofit库动态代理获取请求方法的各个数据
GET、POST请求注解
java
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface GET {
String value();
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface POST {
String value();
}
Retrofit的简单实现:动态代理获取method的GET、POST注解,发起请求:
java
public class Retrofit {
private OkHttpClient mOkHttpClient;
private static final MediaType MEDIA_TYPE = MediaType.get("application/json; charset=UTF-8");
public Retrofit(OkHttpClient mOkHttpClient) {
this.mOkHttpClient = mOkHttpClient;
}
public <T> T create(Class<T> service) {
Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[]{service}, new InvocationHandler() {
@Override
public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
Annotation[] annotations = method.getAnnotations();
for (Annotation annotation: annotations) {
if (annotation instanceof GET) {
return parseGet(((GET) annotation).value());
} else if (annotation instanceof POST){
return parsePost(((POST) annotation).value(), method, objects);
}
}
return null;
}
});
return null;
}
/**
* 处理GET请求信息获取并发起请求
* @param url
* @return
*/
private Call parseGet(String url) {
Request request = new Request.Builder()
.get()
.url(url)
.build();
return mOkHttpClient.newCall(request);
}
/**
* 处理POST请求信息获取并发起请求
* @param url
* @return
*/
private Call parsePost(String url, Method method, Object[] args) {
Type[] genericParameterTypes = method.getGenericParameterTypes();//获取方法泛型
if (genericParameterTypes.length > 0) {
Object o = new Gson().fromJson((String) args[0], genericParameterTypes[0]);
Request request = new Request.Builder()
.url(url)
.post(RequestBody.create(MEDIA_TYPE, o.toString()))
.build();
return mOkHttpClient.newCall(request);
}
return null;
}
}