您的位置:首页 > 移动开发 > Android开发

来,咱们自己写一个Android的IOC框架!

2015-12-12 23:34 459 查看

到目前位置,afinal开发框架也是用了好几个月了,还记得第一次使用注释完成控件的初始化和事件绑定的时候,当时的心情是多么的兴奋— —代码竟然可以这样写!然后随着不断的学习,也慢慢的对IOC框架和注解反射等东西有了一点简单的了解,之前的一篇文章简单的介绍了一下Java的反射机制,今天的文章,就完成一个简单的,基于IOC的小Demo,让大家慢慢的对IOC有一点简单的了解。

首先,什么是IOC呢?

控制反转(Inversion of Control,英文缩写为IoC)是一个重要的面向对象编程的法则来削减计算机程序的耦合问题,也是轻量级的Spring框架的核心。 控制反转一般分为两种类型,依赖注入(Dependency Injection,简称DI)和依赖查找。依赖注入应用比较广泛。

我们下面要完成的,就是Android中依赖注入的实现。

首先,看我们的项目结构



结构很简单,一个基类,一个子类,一个自定义注释类型,一个布局文件。

下面看代码的具体实现

首先看最重要的基类

BaseActivity.java

package com.example.iocdemo;

import java.lang.reflect.Field;

import android.app.Activity;
import android.content.Context;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Toast;

public class BaseActivity extends Activity {

protected Context mContext = this;

/**
* 实现IOC注入
*
* @param baseActivity
*/
public void initInjectedView(Object baseActivity) {
// 获取所有的成员变量
Field[] fields = baseActivity.getClass().getDeclaredFields();
if (fields != null && fields.length > 0) {
// 遍历成员变量
for (Field field : fields) {
try {
// 抑制权限检查
field.setAccessible(true);
// 获取成员变量的注释类
ViewInject viewInject = field
.getAnnotation(ViewInject.class);
// 如果注释类不为空,即成员变量是使用注释的方式进行声明的
if (viewInject != null) {
// 获取注释中的id
int id = viewInject.id();
// 设置字段值
field.set(this,
((Activity) baseActivity).findViewById(id));
// 将实例化好的View对象取出
View view = (View) field.get(this);
// 绑定监听事件
view.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
Toast.makeText(mContext, "别点人家吖!",
Toast.LENGTH_SHORT).show();
}
});
}

} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}


在这个类里面,我们完成了IOC注入方法的编写,自定义的注释类型代码如下:

package com.example.iocdemo;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ViewInject {
public int id();
}
@Target(ElementType.FIELD)这句代码实现的是控制注释的位置为字段,或者说是成员变量,因为我们要完成的是控件的注释,和时间绑定,因此,我们设置为ElementType.FIELD就可以。

@Retention是一个enum类型,共有三个值,分别是SOURCE,CLASS 和 RUNTIME.。

SOURCE代表的是这个Annotation类型的信息只会保留在程序源码里,源码如果经过了编译之后,Annotation的数据就会消失,并不会保留在编译好的.class文件里面。

ClASS的意思是这个Annotation类型的信息保留在程序源码里,同时也会保留在编译好的.class文件里面,在执行的时候,并不会把这一些信息加载到虚拟机(JVM)中去.注意一下,当你没有设定一个Annotation类型的Retention值时,系统默认值是CLASS.

RUNTIME,表示在源码、编译好的.class文件中保留信息,在执行的时候会把这一些信息加载到JVM中去的。

因为我们需要在JVM把我们的class文件加载进入之后,完成注入,因此,我们选择这个属性。

好了,现在我们知道如何简单的定义一个自定义的注释类型,并且用代码实现了代码注入和事件绑定,下面,我们看一下在我们的程序中,如何使用。

下面是我们在Activity的代码

package com.example.iocdemo;

import android.os.Bundle;
import android.widget.Button;

public class MainActivity extends BaseActivity {

//用注释进行控件的初始化
@ViewInject(id = R.id.btn)
Button btn;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//进行注入
initInjectedView(this);
}

}


下面是我们的运行结果

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