浅析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
浅析android中的依赖注入的更多相关文章
- 用Dagger2在Android中实现依赖注入
		依赖注入这个模式(模式已经用烂了,这里再烂一次)是用来给应用的各部分解耦的.使应用开发更加可扩展,更容易维护.通过本文你会学到如何使用Dagger2来处理依赖. 简介 如果以对象需要另外的一个对象才能 ... 
- Andriod中的依赖注入
		Web后端开发者应该对依赖注入都比较熟悉,至于Android又是如何进行依赖注入的呢?在这篇文章中,让我们一起通过一个例子了解一下在Android中进行依赖注入的好处. AndroidAnnotati ... 
- Android 和 Dagger 2 中的依赖注入
		原文:Dependency Injection in Android with Dagger 2 作者:Joe Howard 译者:kmyhy 在现代开发团队中到处充斥着"你一定要用依赖注入 ... 
- ASP.NET Core 中文文档 第四章 MVC(3.8)视图中的依赖注入
		原文:Dependency injection into views 作者:Steve Smith 翻译:姚阿勇(Dr.Yao) 校对:孟帅洋(书缘) ASP.NET Core 支持在视图中使用 依赖 ... 
- 在WPF中使用依赖注入的方式创建视图
		在WPF中使用依赖注入的方式创建视图 0x00 问题的产生 互联网时代桌面开发真是越来越少了,很多应用都转到了浏览器端和移动智能终端,相应的软件开发上的新技术应用到桌面开发的文章也很少.我之前主要做W ... 
- ASP.NET Core 在 JSON 文件中配置依赖注入
		前言 在上一篇文章中写了如何在MVC中配置全局路由前缀,今天给大家介绍一下如何在在 json 文件中配置依赖注入. 在以前的 ASP.NET 4+ (MVC,Web Api,Owin,SingalR等 ... 
- 在.NET Core控制台程序中使用依赖注入
		之前都是在ASP.NET Core中使用依赖注入(Dependency Injection),昨天遇到一个场景需要在.NET Core控制台程序中使用依赖注入,由于对.NET Core中的依赖注入机制 ... 
- ASP.NET Core中的依赖注入(1):控制反转(IoC)
		ASP.NET Core在启动以及后续针对每个请求的处理过程中的各个环节都需要相应的组件提供相应的服务,为了方便对这些组件进行定制,ASP.NET通过定义接口的方式对它们进行了"标准化&qu ... 
- ASP.NET Core中的依赖注入(2):依赖注入(DI)
		IoC主要体现了这样一种设计思想:通过将一组通用流程的控制从应用转移到框架之中以实现对流程的复用,同时采用"好莱坞原则"是应用程序以被动的方式实现对流程的定制.我们可以采用若干设计 ... 
随机推荐
- JAVA Eclipse 创建android  xml看不到预览怎么办
			电机安卓图标,设置为更低的API版本即可 
- webstrom 代码工具(转http://www.cnblogs.com/tangdanni11/p/5149063.html)
			Emmet的前身是大名鼎鼎的Zen coding,如果你从事Web前端开发的话,对该插件一定不会陌生.它使用仿CSS选择器的语法来生成代码,大大提高了HTML/CSS代码编写的速度,比如下面的演示: ... 
- Java 使用StringBuffer注意
			Stringbuffer使用注意 问题背景: 模拟客户端使用Socket请求服务器核心系统,核心系统正常响应,内容较大,近2715KB,大于2.6M多. 使用指定编码GBK来接收响应内容到过程中没 ... 
- VueJS条件语句:v-if、v-else、v-else-if
			HTML:if-else <!DOCTYPE html> <html> <head> <meta charset="utf-8"> ... 
- 转:DDR中端接技术基本概念
			DDR中端接技术基本概念 版权声明:转载请注明出处:http://blog.csdn.net/lg2lh https://blog.csdn.net/lg2lh/article/details/90 ... 
- Command &Prompt Here
			Windows Registry Editor Version 5.00 [HKEY_CLASSES_ROOT\Directory\shell\Command Prompt Here]@=" ... 
- php图片本身有错无法显示的解决办法
			1.取消所有错误提示 2.如果没有报错,在header前(即设置输出格式前)使用ob_clean(); 
- springboot输出日志到指定目录,简单粗暴,springboot输出mybatis日志
			springboot官方文档地址https://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#boot- ... 
- yii2学习笔记
			之前看过Yii2框架,也在其他框架实现其Gii手脚架功能,现在开始使用Yii做项目,顺便记录一下学习笔记 先推荐一个网址 Yii2速查表(中文版)http://nai8.me/tool-sc.html ... 
- hdu4612 无向图中随意加入一条边后使桥的数量最少 /  无向图缩点+求树的直径
			题意如上,含有重边(重边的话,俩个点就能够构成了边双连通). 先缩点成树,在求数的直径,最远的连起来,剩下边(桥)的自然最少.这里学习了树的直径求法:第一次选随意起点U,进行bfs,到达最远的一个点v ... 
