自己动手写一个简单的IOC框架,使用注解绑定资源和事件

自己动手写一个简单的IOC框架,使用注解绑定资源和事件

程序员都是懒惰的;事实证明,懒人才能改变世界、创造未来。

几行代码就能搞定的一个简单IOC框架,使用方式如下:

public class MainActivity extends AppCompatActivity {


    /**
     * 属性注解
     */
    @ViewInject(R.id.tv)
    TextView mTv;


    @ViewInject(R.id.btn)
    Button mBtn;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        // 注入
        ViewUtils.inject(this);


        mTv.setText("You need 安慰");
    }


    /**
     * 方法注解
     * @param view
     */
    @ViewClick({R.id.btn,R.id.tv})
    private void click(View view) {
        Toast.makeText(this, view.getId() + "", Toast.LENGTH_SHORT).show();
    }
}

庖丁解牛

需要使用@interface申明注解类,主要使用的注解有:

@Retention

申明注解生效的时期,可以选择三个参数:SOURCE、CLASS、RUNTIME。

  • SOURCE:Annotation is only available in the source code.

  • CLASS:Annotation is available in the source code and in the class file, but not at runtime. This is the default policy.

  • RUNTIME:Annotation is available in the source code, the class file and is available at runtime.

因为我们是在运行时对注解进行反射操作,所以这里我们选择 RUNTIME。

@Target

申明注解在哪些成员上可用,不申明默认全部可用,常用可选择的有:TYPE、FIELD、METHOD、CONSTRUCTOR等

对具体的类进行分析

  • ViewInject 注解类
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface ViewInject {


    /**
     * 注解参数名和参数类型
     */
    int value();
}
  • ViewClick 注解类
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface ViewClick {


    /**
     * 可以同时绑定多个View的点击事件
     */
    int[] value();
}
  • ViewUtils 工具类
public class ViewUtils {


    /**
     * 执行注入操作
     *
     * @param activity
     */
    public static void inject(final Activity activity) {


        /**
         * 使用getDeclaredFields()可以获取到类中所有的Filed,包括私有的。
         */
        Field[] fields = activity.getClass().getDeclaredFields();
        //遍历Fields
        for (int i = 0; i < fields.length; i++) {


            Field field = fields[i];


            //设置私有的也能访问到
            field.setAccessible(true);


            //获取指定注解对象
            ViewInject annotation = field.getAnnotation(ViewInject.class);


            //如果该Filed上有这个注解
            if (annotation != null) {
                //获取注解的值
                int id = annotation.value();


                View view = activity.findViewById(id);


                try {
                    // 给activity中的view设值
                    field.set(activity, view);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        }


        /**
         * 给View设置点击监听事件
         * 使用getDeclaredMethods()可以获取到类中所有的Method,包括私有的。
         */
        Method[] methods = activity.getClass().getDeclaredMethods();
        for (int i = 0; i < methods.length; i++) {
            final Method method = methods[i];


            method.setAccessible(true);


            ViewClick annotation = method.getAnnotation(ViewClick.class);


            if (annotation != null) {


                // 这是个int[]形式,可能有多个值
                int[] ids = annotation.value();


                for (int j = 0; j < ids.length; j++) {
                    // 更具获取到的id 去设置点击监听事件
                    final View button = activity.findViewById(ids[j]);
                    button.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {

                            try {
                                // 调用指定方法
                                method.invoke(activity, button);
                            } catch (IllegalAccessException e) {
                                e.printStackTrace();
                            } catch (InvocationTargetException e) {
                                e.printStackTrace();
                            }
                        }
                    });
                }
            }
        }
    }
}

总结

简单的使用注解和反射就完成一个简单IOC框架,可以减少很多findViewById的代码呢。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值