http://blog.csdn.net/blog_wang/article/details/38468547

  1. FinalActivity

    android中的ioc框架,完全注解方式就可以进行UI绑定和事件绑定

    public class FinalActivityDemo extends FinalActivity {
        //这里的ViewInject就是下面自定义的注解,id和click都是里面定义的方法
        @ViewInject(id = R.id.btn_ok, click="btnOnClick")  Button button
        @ViewInject(id = R.id.tv_show)  TextView textView
        
        protected void onCreate() {
            super.onCreate();
            setContentView(R.layout.activity_main)
        }
        
        private void btnOnClick() {
            textView.setText("dkelk")
        }
    }

我们看看FinalActivity的部分源码:    

protected void onCreate() {
    super.onCreate();
}

public void setContentView(int layoutResourceId) {
    super.setContentView(layoutResourceId);
    //初始化指定View中的注入属性,它是在setContentView之后开始绑定的
    FinalActivity.initInjectedView(this);
}

    

    在介绍initInjectedView之前先了解什么是注释。

    例如:@ovverides:这是内置注解,我们复写方法会自动添加。

          @ViewInject:自定义注解,FinalActivity的注解就在这里,然后上面类就可以用了。

          @Interface是java中表示声明一个注解类的关键词。       

     ElementType和RententionPolicy是2个枚举类

     ElementType: METHOD:方法声明(表示注解是作用在方法上),FIELD:字段声明(表示作用在属性                   上,如上面的Button button),PACKAGE(包声明)等的

     RententionPolicy:RUNNTIME和CLASS,编译器都会将注释记录在类文件中,但RUNNTIME是在程序           运行时VM会保留注释,所以可以通过反射获取到,CLASS就不行。SOURCE是编译器丢弃的注释。

@Target(ElementType.FIELD) //表明注解的是一个字段,如Button button字段,而不是函数等。
@Retention(RententionPolicy.RUNTIME) //表明该注解保存在class字节中可以在运行时获取到
public @interface ViewInject {
    public int id();
    public String click() default "";
    public String longClick() default "";
    public String itemClick() default "";
    public String itemLongClick() default "";
    public Select select() default @Select(selected="");
}


    现在我们来看看FinalActivity.initInjectedView(this);

    public static void initInjectedView(Activity sourceActivity) {
        initInjectedView(sourceActivity, sourceActivity.getWindow().getDecorView());
    }
    
    public static void initInjectedView(Object injectedSource, View sourceView) {
        //通过反射获取activity的所有方法,并过滤出
        Field[] fields = injectedSource.getClass().getDeclaredFields();
        if (fileds != null && fields.length > 0) {
            for (Field field : fields) {
                ViewInject viewInject = field.getAnnonation(ViewInject.class);
                if (viewInject != null) {
                //这里获取的就是我们定义的@ViewInject(id=R.id.btn_click)
                    int viewId = viewInject.id();
                    try {
                        field.setAccessible(true);
                        field.set(injectedSource, sourceView.findViewById(viewId));
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                //这里获取的就是我们定义的@ViewInject(click="btnOnClick"),像id(),Click()等方法都是在public @interface ViewInject{}中定义的  
                String clickMethod = viewInject.click();
                if (!TextUtils.isEmpty(clickMethod)) setViewClickListener(injectedSource, clickMethod);
                String longClickMethod = viewInject.longClick();
                if (!TextUtils.isEmpty(longClickMethod)) setViewLongClickListener(injectedSource, field, longClickMethod);

                String itemClickMethod = viewInject.itemClick();
                if (!TextUtils.isEmpty(itemClickMethod)) setItemClickListener(injectedSource, field, itemClickMethod);

                String itemLongClickMethod = viewInject.itemLongClick();
                if (!TextUtils.isEmpty(longClickMethod)) setViewLongClickListener(injectedSource, field, itemLongClickMethod);

                Select select = viewInject.select();
                if(!TextUtils.isEmpty(select.selected())
                    setViewSelectLisstener(injectedSource, field, select.selected, select.noSelect());   
}}}}


//下面是为view绑定onClick事件:setViewClickListener(injectedSource,field,clickMethod);同样是反射。EventListener暂时就不写了。

private static void setViewClickListener(Object injectedSource,Field field, String clickMethod) {
    try {
        Object obj = field.get(injectedSource);
        if (obj instanceOf View) {
            ((View)obj).setOnClickListener(new EventListener(injectedSource).click(clickMethod));
        }
    } catch(Exception e) {
        e.printStackTrace();
    }
}