这几年针对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中的依赖注入的更多相关文章

  1. 用Dagger2在Android中实现依赖注入

    依赖注入这个模式(模式已经用烂了,这里再烂一次)是用来给应用的各部分解耦的.使应用开发更加可扩展,更容易维护.通过本文你会学到如何使用Dagger2来处理依赖. 简介 如果以对象需要另外的一个对象才能 ...

  2. Andriod中的依赖注入

    Web后端开发者应该对依赖注入都比较熟悉,至于Android又是如何进行依赖注入的呢?在这篇文章中,让我们一起通过一个例子了解一下在Android中进行依赖注入的好处. AndroidAnnotati ...

  3. Android 和 Dagger 2 中的依赖注入

    原文:Dependency Injection in Android with Dagger 2 作者:Joe Howard 译者:kmyhy 在现代开发团队中到处充斥着"你一定要用依赖注入 ...

  4. ASP.NET Core 中文文档 第四章 MVC(3.8)视图中的依赖注入

    原文:Dependency injection into views 作者:Steve Smith 翻译:姚阿勇(Dr.Yao) 校对:孟帅洋(书缘) ASP.NET Core 支持在视图中使用 依赖 ...

  5. 在WPF中使用依赖注入的方式创建视图

    在WPF中使用依赖注入的方式创建视图 0x00 问题的产生 互联网时代桌面开发真是越来越少了,很多应用都转到了浏览器端和移动智能终端,相应的软件开发上的新技术应用到桌面开发的文章也很少.我之前主要做W ...

  6. ASP.NET Core 在 JSON 文件中配置依赖注入

    前言 在上一篇文章中写了如何在MVC中配置全局路由前缀,今天给大家介绍一下如何在在 json 文件中配置依赖注入. 在以前的 ASP.NET 4+ (MVC,Web Api,Owin,SingalR等 ...

  7. 在.NET Core控制台程序中使用依赖注入

    之前都是在ASP.NET Core中使用依赖注入(Dependency Injection),昨天遇到一个场景需要在.NET Core控制台程序中使用依赖注入,由于对.NET Core中的依赖注入机制 ...

  8. ASP.NET Core中的依赖注入(1):控制反转(IoC)

    ASP.NET Core在启动以及后续针对每个请求的处理过程中的各个环节都需要相应的组件提供相应的服务,为了方便对这些组件进行定制,ASP.NET通过定义接口的方式对它们进行了"标准化&qu ...

  9. ASP.NET Core中的依赖注入(2):依赖注入(DI)

    IoC主要体现了这样一种设计思想:通过将一组通用流程的控制从应用转移到框架之中以实现对流程的复用,同时采用"好莱坞原则"是应用程序以被动的方式实现对流程的定制.我们可以采用若干设计 ...

随机推荐

  1. Python爬虫爬取美剧网站

    一直有爱看美剧的习惯,一方面锻炼一下英语听力,一方面打发一下时间.之前是能在视频网站上面在线看的,可是自从广电总局的限制令之后,进口的美剧英剧等貌似就不在像以前一样同步更新了.但是,作为一个宅diao ...

  2. 重读金典------高质量C编程指南(林锐)-------第七章 内存管理

    2015/12/10补充: 当我们需要给一个数组返回所赋的值的时候,我们需要传入指针的指针.当我们只需要一个值的时候,传入指针即可,或者引用也可以. 结构大致如下: char* p = (char*) ...

  3. shell脚本实现定时重启进程

    ##############################Deploy crontab for yechang ad*******eta restart ###################### ...

  4. 试验笔记 - 使用7-ZIP压缩来减小APK安装包体积

    7-ZIP版本:9.20 x86 And x64 Windows(2010-11-18) 1. 将APK包解压到文件夹2. 全选所有文件,右键“添加到压缩包”3.“压缩格式”必须“zip”4.“压缩等 ...

  5. 一致性哈希算法(c#版)

    最近在研究"一致性HASH算法"(Consistent Hashing),用于解决memcached集群中当服务器出现增减变动时对散列值的影响.后来 在JAVAEYE上的一篇文章中 ...

  6. Gmail上不去怎么办?

    近期非常多人反映Gmail上不去.每到重大政治事件附近,国家的防火墙就会加固一些. 事实上仅仅要下一个软件就能够轻松解决Google.Gmail上不去的问题. 下载地址 下载解压后点击"我要 ...

  7. js 第二篇 (DOM 操作)

    DOM 节点含有:元素节点,属性节点,文本节点. document.getElementById("id") //通过页面元素ID 值 捕获元素对象,得到的值为一个object 1 ...

  8. Jenkins--Run shell command in jenkins as root user?

    You need to modify the permission for jenkins user so that you can run the shell commands. You can i ...

  9. CI学习总结

    1.CI自定义配置文件: 如:config/test.php <?php $config['test']['good'] = array('aa','bb'); 在控制器中这样调用: <? ...

  10. 九度OJ 1010:A + B (字符串处理)

    时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:7166 解决:3646 题目描述: 读入两个小于100的正整数A和B,计算A+B. 需要注意的是:A和B的每一位数字由对应的英文单词给出. ...