Android手动编写ButterKnife编译时注解框架
2017-08-27 13:42
411 查看
我们在项目中经常使用ButterKnife注解等框架,那里面的实现原理是什么呢?其实内部原理比较简单,今天就跟大家一起分享一下。
先上效果:
这就是我用自己写的编译时注解框架实现的效果。
MainActivity代码:
可以看到用法都是和ButterKnife一样的。那我们就从上往下看,先看InjectView里面的代码:
这里面的代码很简单,主要就是一个接口和注解。解释一下注解。
@Target: @Target 用于指定该注解可以声明在哪些成员上,常见的值有FIELD和METHOD,如果不设置值得话,默认可以添加到任何元素上,但是一般不推荐这样使用。
这里的话我们设置的值是FIELD。
@Retention: 用于声明该注解生效的生命周期,有三个值可选
* 1.RetentionPolicy.SOURCE:注解之保留在源码上,编译成class的时候自动被编译器抹除
* 2.RetentionPolicy.CLASS:注解只留到字节码上,VM加载字节码时自动抹除
* 3.RetentionPolicy.RUNTIME:注解永久保留,可以被VM加载时加载到内存中
这里我们是想VM在运行时对Field上的注解进行反射,所以设置为第三个。
@interface:是声明注解类的组合关键字
然后是OnClick里面的代码:
这里和刚才的都是差不多的,主要是设置@Target的值为METHOD,意思应该都是懂得。
最后是我们的重点InjectViewUtils类,代码如下:
里面主要就是一个方法,通过反射获取字段的id,然后获取控件,然后做相应的设定,不了解反射的话,可以看下反射的知识,希望对大家有所帮助。
点击下载源码
先上效果:
这就是我用自己写的编译时注解框架实现的效果。
MainActivity代码:
@InjectView(R.id.btn1) Button btn1; @InjectView(R.id.btn2) Button btn2; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); InjectViewUtils.inject(this); btn1.setText("点击我111啊!!!"); btn2.setText("点击我222啊!!!"); } @OnClick({R.id.btn1, R.id.btn2}) public void click(View view) { switch (view.getId()) { case R.id.btn1: Toast.makeText(this,"我是按钮11111",Toast.LENGTH_SHORT).show(); break; case R.id.btn2: Toast.makeText(this,"我是按钮22222",Toast.LENGTH_SHORT).show(); break; } }
可以看到用法都是和ButterKnife一样的。那我们就从上往下看,先看InjectView里面的代码:
@Target({ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) public @interface InjectView { int value(); }
这里面的代码很简单,主要就是一个接口和注解。解释一下注解。
@Target: @Target 用于指定该注解可以声明在哪些成员上,常见的值有FIELD和METHOD,如果不设置值得话,默认可以添加到任何元素上,但是一般不推荐这样使用。
这里的话我们设置的值是FIELD。
@Retention: 用于声明该注解生效的生命周期,有三个值可选
* 1.RetentionPolicy.SOURCE:注解之保留在源码上,编译成class的时候自动被编译器抹除
* 2.RetentionPolicy.CLASS:注解只留到字节码上,VM加载字节码时自动抹除
* 3.RetentionPolicy.RUNTIME:注解永久保留,可以被VM加载时加载到内存中
这里我们是想VM在运行时对Field上的注解进行反射,所以设置为第三个。
@interface:是声明注解类的组合关键字
然后是OnClick里面的代码:
@Target({ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) public @interface OnClick { int[] value(); }
这里和刚才的都是差不多的,主要是设置@Target的值为METHOD,意思应该都是懂得。
最后是我们的重点InjectViewUtils类,代码如下:
public static void inject(final Activity activity) { Class clazz = activity.getClass(); //通过字节码获取field的时候一定要用getDeclaredField(),只有该方法才能获取到任何权限修饰符的Field Field[] field = clazz.getDeclaredFields(); for (int i = 0; i < field.length; i++) { Field f = field[i]; //设置为可访问,暴力反射,私有也能访问 f.setAccessible(true); //获取到字段的注解对象 InjectView inject = f.getAnnotation(InjectView.class); if (inject == null) { continue;//如果该方法上没有注解,循环下一个 } int id = inject.value();//获取注解中的值 View v = activity.findViewById(id);//获取控件 try { f.set(activity,v);//将控件设置给field对象 } catch (IllegalAccessException e) { e.printStackTrace(); } } Method[] method = clazz.getDeclaredMethods(); for (int i = 0; i < method.length; i++) { final Method m = method[i]; OnClick click = m.getAnnotation(OnClick.class); if (click == null) { continue; } int[] value = click.value(); for (int j = 0; j < value.length; j++) { int id = value[j]; final View v = activity.findViewById(id); v.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { try { m.invoke(activity,v);//反射调用用户设定的方法 } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } }); } } }
里面主要就是一个方法,通过反射获取字段的id,然后获取控件,然后做相应的设定,不了解反射的话,可以看下反射的知识,希望对大家有所帮助。
点击下载源码
相关文章推荐
- Android进阶系列8-编译时注解框架ButterKnife浅析
- Android 注解框架 Butterknife的核心代码分析笔记
- Android Studio注解框架的偷懒插件Android Butterknife Zelezny
- Android Studio上方便使用butterknife注解框架的偷懒插件Android Butterknife Zelezny
- android注解框架ButterKnife详细使用文档(v7.0.1)
- Android Butterknife框架 注解攻略:
- 注解框架Android Butter Knife的介绍
- Android-第三方框架ButterKnife(注解框架)
- android(android studio)中使用注解框架butterknife
- Android butterknife框架 注解攻略
- Android Studio上方便使用butterknife注解框架的偷懒插件Android Butterknife Zelezny
- Android 仿ButterKnife写自己的IOC注解框架
- Android Butterknife框架 注解攻略
- Android快速开发工具ButterKnife Zelezny注解框架使用教程
- Android butterknife注解框架
- Android Butterknife框架 注解攻略
- (2016.5.26更新8.0.1失效问题)Android Studio上使用Butterknife注解框架与插件Android Butterknife Zelezny
- Android—慎用注解框架butterknife-7.0.1
- Android ButterKnife注解框架
- Android注解框架Butter Knife