您的位置:首页 > 编程语言 > Java开发

自定义一个Java运行时注解框架

2017-12-08 13:26 501 查看
随着项目开发经验的累计,逐渐接触到很多成熟的注解框架(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);
}
}
}


如何使用呢?

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java 框架