IOC
控制反转(Inversion of Control,英文缩写为IoC)是一个重要的面向对象编程的法则来削减计算机程序的耦合问题,也是轻量级的Spring框架的核心IOC一般分为两种,一种是依赖注入,另一种是依赖查找。
而在xutils框架中就是用到了依赖注入的方式。
依赖注入
为什么要用到依赖注入?
控制反转用于解耦,解的究竟是谁和谁的耦?这是我在最初了解依赖注入时候产生的第一个问题。
在Android中,我们需要获取一个控件的对象,怎么做?
btn=(Button) findViewById(R.id.btn);
是不是这样做?。。。那如果我们的控件比较多,每次都要用到findViewById是不是就感觉代码比较多,写起来也比较无聊。
xutils 框架的注入相信大家都用过
@ViewInject(R.id.btn)
private Button btn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
x.view().inject(this);
btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Toast.makeText(getApplicationContext(), "这是Btn", Toast.LENGTH_SHORT).show();
}
});
}
没错,就是这样,用大家都会用,但你们知道它内部到底是怎么实现的呢,下面就由我来分析下他的源代码。
public class I {
public static void InjectActivityView(Activity activity){
//获得activity类
Class<? extends Activity> clazz = activity.getClass();
//获取类中的所有属性
Field[] fields = clazz.getDeclaredFields();
//循环遍历
for (Field field : fields) {
//如果属性是私有的就需要执行这个代码
field.setAccessible(true);
//获取标记在属性上的注解类
ZRView zrView = field.getAnnotation(ZRView.class);
if(zrView==null)continue;
//获得value值,也就是控件的ID值
int id=zrView.value();
try {
//获取类中的findViewById方法
Method method = clazz.getMethod("findViewById");
//执行方法获得结果
Object invoke = method.invoke(clazz,id);
//把得到的值赋给属性
field.set(clazz, invoke);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
这三行代码是不是很难懂,其实我也不太懂,意思就是执行方法,得到返回值
//获取类中的findViewById方法
Method method = clazz.getMethod("findViewById");
//执行方法获得结果
Object invoke = method.invoke(clazz,id);
//把得到的值赋给属性
field.set(clazz, invoke);
这几行代码其实就是这样的
View view=activity.findViewById(id);
field.set(clazz, view);
这样应该能理解了吧。
好了代码这么多,感觉是不是很少?这只是activity的View注入,后面我会讲解Lyout注入fragment的View注入以及ViewHolder的View注入。
看完这是不是还是感觉少点了什么???没错,少了一段重要的代码:注解类
@Target(ElementType.FIELD)//标识在属性上的注解
@Retention(RetentionPolicy.RUNTIME)//整个程序运行期间都有效
public @interface ZRView {
int value();
}
上面就是标注在控件上的注解类使用代码如下,
@ZRView(R.id.btn)
private Button btn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
I.InjectActivityView(this);
}
}
未完待续····期待下一章的讲解请评论下吧 谢谢。。。