zoukankan      html  css  js  c++  java
  • 浅析android中的依赖注入

    这几年针对Android推出了不少View注入框架,例如ButterKnife。我们首先来了解一下使用这些框架有什么好处,其实好处很明显:它可以减少大量的findViewById以及setOnClickListener代码,简化了代码,让我们的代码看起来条理更清晰,可读性变强。
    
         可能大多数对于这一类框架,都只是停留在用的阶段,但是作为一个程序员,我们有必要去了解它是如何实现的。其实它的原理也没有多复杂,用到了java中反射和注解的相关知识,所以对反射和注解了解不多的朋友可以先找一下相关资料了解一下。
    
    关于注解,我推荐一篇文章(简单易懂)http://mp.weixin.qq.com/s/NwlIy_knmx4Es7kFnk0gRQ
    
    今天的任务呢就是教大家如何一步一步简单的实现一个类似 ButterKnife的依赖注入的效果:
    
    第一步:我们需要自定义注解,如下:
    
    //用于初始化view的
    
        @Target(ElementType.FIELD)
        @Retention(RetentionPolicy.RUNTIME)
        public @interface BindView {
            int value() default 0;
        }
    
    //用于绑定点击事件的
    
        @Target(ElementType.METHOD)
        @Retention(RetentionPolicy.RUNTIME)
        public @interface BindClick {
            int value() default 0;
        }
    
    从上面的Target里面的值我们可以知道,这两个注解一个是作用于属性,一个是作用于方法的。这里提醒一下,如果如果只有一个参数成员,最好把参数名称设为value,这里可以补一句因为使用该注解时,value作为key可省略,在使用的时候比较方便。
    
    第二步:设置注解
    
            @BindView(R.id.button)
            private Button mButton;
            @BindView(R.id.textview)
            private TextView mTextView;
    
    
            @BindClick(R.id.button)
            private void onButtonClick(){
                Toast.makeText(this,"Button被点击了",Toast.LENGTH_SHORT).show();
            }
            @BindClick(R.id.textview)
            private void onTextViewClick(){
                Toast.makeText(this,"TextView被点击了",Toast.LENGTH_SHORT).show();
            }
    
    第三步:获取注解,进行处理
    
        public class InjectUtils {
            public static void inject(final Activity activity) {
                //遍历属性,对设置注解的view进行初始化
                Class<Activity> activityClass= (Class<Activity>) activity.getClass();
                Field fields[]=activityClass.getDeclaredFields();
                for(Field field:fields){
                    if(field.isAnnotationPresent(BindView.class)){
                        int viewId=field.getAnnotation(BindView.class).value();
                        View view=activity.findViewById(viewId);
                        try {
                            //这一行代码是必须的,否则直接调用set方法不生效
                            field.setAccessible(true);
                            field.set(activity,view);
                        } catch (IllegalAccessException e) {
                            e.printStackTrace();
                        }
                    }
                }
                //遍历方法 将设置注解的方法绑定到相应的view的点击事件中
                Method methods[]=activityClass.getDeclaredMethods();
                for(final Method method:methods){
                    BindClick bindClick=method.getAnnotation(BindClick.class);
                    if(bindClick!=null){
                        int viewId=bindClick.value();
                        activity.findViewById(viewId).setOnClickListener(new View.OnClickListener() {
                            @Override
                            public void onClick(View view) {
                                try {
                                    //调用该方法
                                    method.setAccessible(true);
                                    method.invoke(activity);
                                } catch (IllegalAccessException e) {
                                    e.printStackTrace();
                                } catch (InvocationTargetException e) {
                                    e.printStackTrace();
                                }
                            }
                        });
                    }
                }
            }
        }
    
    
    第四步:其实上面已经完成了处理,我们只需要调用一下就可以了,像下面那样:
    
                setContentView(R.layout.activity_main);
                //必须放在setContentView后面
                InjectUtils.inject(this);
    
    下面,我们就可以运行一下项目,看看是不是达到我们的效果了。
    
    项目地址:https://github.com/coder-xiaoshuai/AnnotationDemo.git
  • 相关阅读:
    小组自评、互评及反馈
    "一个程序员的生命周期"读后感
    阅读《构建之法》第10-12章
    阅读《构建之法》第8,9,10章
    冒泡算法程序分析树的评论
    1014 C语言文法定义与C程序的推导过程
    0917 实验一词法分析程序
    0909 我与编译原理不得不说的秘密
    复利计算器4
    复利及单利计算
  • 原文地址:https://www.cnblogs.com/Free-Thinker/p/9402658.html
Copyright © 2011-2022 走看看