自定义一个Java运行时注解框架
程序员文章站
2022-06-16 17:26:25
...
随着项目开发经验的累计,逐渐接触到很多成熟的注解框架(ButterKnife,Retrofit等等),框架是为了减少人力成本,所以框架就会要求计算机去做一些人不想做的重复劳动的工作(比如findViewById),注解框架分为编译时注解和运行时注解
编译时框架:编译的时候耗时,但是不影响运行效果
运行时框架:编译速度不会影响但是会影响运行效果
其实超大项目才会考虑到运行时和编译时的效率问题,小型demo反射注解框架的耗时对性能的消耗几乎为0,一句话总结就是如果你对反射注解理解的不深刻,请不要在公司项目上使用
/**
* @Description:
* @Author: Liangchaojie
* @Create On 2017/12/8 10:17
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface BindView {
@IdRes int value();
}
/**
* @Description:
* @Author: Liangchaojie
* @Create On 2017/12/8 10:19
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Onclick {
@IdRes int[] value();
}
package com.test.inject;
import android.app.Activity;
import android.content.Context;
import android.os.Build;
import android.util.Log;
import android.view.View;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
/**
* @Description:
* @Author: Liangchaojie
* @Create On 2017/12/8 10:20
*/
public class Injector {
public static void init(Activity context){
inject(context,context.getWindow().getDecorView());
}
private static void inject(Activity context, View decorView) {
Class c = context.getClass();
if(c==null) return;
HashMap<Integer, View> viewHashMap = new HashMap<>();
Field[] fields = c.getDeclaredFields();
Method[] methods = c.getDeclaredMethods();
for(Field field:fields){
if(field.isAnnotationPresent(BindView.class)){
field.setAccessible(true);
int viewId=field.getAnnotation(BindView.class).value();
View view = decorView.findViewById(viewId);
try {
field.set(context,view);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
viewHashMap.put(viewId, view);
}
}
for (Method method:methods){
if(method.isAnnotationPresent(Onclick.class)){
method.setAccessible(true);
int[] values = method.getAnnotation(Onclick.class).value();
for(int i:values){
if(viewHashMap.containsKey(i)){
viewHashMap.get(i).setOnClickListener(new Click(method,context));
}
}
}
}
}
private static class Click implements View.OnClickListener{
private Method method;
private Context context;
public Click(Method method, Activity context) {
this.method = method;
this.context = context;
}
private void checkParam(View v) {
Class<?>[] parameterTypes = method.getParameterTypes();
try {
if(parameterTypes.length==0){
method.invoke(context);
}
if(parameterTypes.length>1 ){
throw new IllegalArgumentException("最多只能有一个参数!");
}
if(parameterTypes.length==1){
method.invoke(context, v);
}
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
@Override
public void onClick(View v) {
checkParam(v);
}
}
}
如何使用呢?
上一篇: html与js和php之间实现数据交互
下一篇: php代码的编译与执行