Daager2-初认识一

背景:

有什么能比那把黄油刀(butterknife)更加犀利的名字唯有dagger了

最早的版本Dagger1 由Square公司开发。依赖注入框架主要用于模块间解耦,提高代码的健壮性和可维护性。Dagger 这个库的取名不仅仅来自它的本意“匕首”同时也暗示了它的原理

Dagger2 是一个Android依赖注入框架,由谷歌开发,因为主流是Dagger2所以接下来我们直接学习如何使用它

认识依赖注入

说了那么多,那到底依赖注入是什么呢?上代码:

public class MainActivity extends AppCompatActivity {    User user;    public void setUser(User user) {        this.user = user;    }

依赖:MainActivity 包含了一个User对象,我们就说MainActivity 依赖于user;
注入:因为user对象是通过传递初始的,不是直接new出的对象,所以这样的方式就叫做注入;
通过上面简单的一小段代码估计大家对依赖注入有了了解,通过依赖注入可以有效的减少我们的耦合,既然这样可以实现依赖注入,为什么还需要dagger这样的第三方库处理呢?

1.增加开发效率、省去重复的简单体力劳动
首先new一个实例的过程是一个重复的简单体力劳动,dagger2完全可以把new一个实例的工作做了,因此我们把主要精力集中在关键业务上、同时也能增加开发效率上。
省去写单例的方法,并且也不需要担心自己写的单例方法是否线程安全,自己写的单例是懒汉模式还是饿汉模式。因为dagger2都可以把这些工作做了。

2.更好的管理类实例
每个app中的ApplicationComponent管理整个app的全局类实例,所有的全局类实例都统一交给ApplicationComponent管理,并且它们的生命周期与app的生命周期一样。
每个页面对应自己的Component,页面Component管理着自己页面所依赖的所有类实例。
因为Component,Module,整个app的类实例结构变的很清晰。

3.解耦
假如不用dagger2的话,一个类的new代码是非常可能充斥在app的多个类中的,假如该类的构造函数发生变化,那这些涉及到的类都得进行修改。设计模式中提倡把容易变化的部分封装起来。

说了那么多概念,估计大家已经对dagger有了一定的了解,那开咱们的使用吧,毕竟实战才是最有用的嘛

使用

还是结合一开始的例子,我们采用dagger的方式看如何给MainActivity 传递一个依赖的user对象

1.加入依赖包

Github-地址

// Add plugin https://bitbucket.org/hvisser/android-aptbuildscript {  repositories {    mavenCentral()  }  dependencies {    classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'  }}// Apply pluginapply plugin: 'com.neenbedankt.android-apt'// Add Dagger dependenciesdependencies {  compile 'com.google.dagger:dagger:2.x'  apt 'com.google.dagger:dagger-compiler:2.x'}

2.注解方法

  • @Inject: 通常在需要依赖的地方使用这个注解。换句话说,你用它告诉Dagger这个类或者字段需要依赖注入。这样,Dagger就会构造一个这个类的实例并满足他们的依赖。
  • @Module: Modules类里面的方法专门提供依赖,所以我们定义一个类,用 @Module注解,这样Dagger在构造类的实例的时候,就知道从哪里去找到需要的 依赖。modules的一个重要特征是它们设计为分区并组合在一起(比如说,在我们的app中可以有多个组成在一起的modules)。
  • @Provides: 在modules中,我们定义的方法是用这个注解,以此来告诉Dagger我们想要构造对象并提供这些依赖。
  • @Component: Components从根本上来说就是一个注入器,也可以说是@Inject和@Module的桥梁,它的主要作用就是连接这两个部分。 Components可以提供所有定义了的类型的实例,比如:我们必须用@Component注解一个接口然后列出所有的   @Modules组成该组件,如 果缺失了任何一块都会在编译的时候报错。所有的组件都可以通过它的modules知道依赖的范围。
  • @Scope: Scopes可是非常的有用,Dagger2可以通过自定义注解限定注解作用域。后面会演示一个例子,这是一个非常强大的特点,因为就如前面说的一样,没必要让每个对象都去了解如何管理他们的实例

可以粗滤的过一遍,估计看完也是一头雾水,还是投入到实战中去认识吧!

3.初始user对象

和传统方法一样不多讲了,设置一些属性罢了

public class User {    private String name;    private String sex;    private String ads;    ******get/set********** }

4.生成对应module对象

module类就是给user初始化并且提供外部调用的类,这里类中我们需要给user初始,并且返回给dagger一个可调用的对象

@Modulepublic class UserModule {    @Provides    User provideUser(){        return new User("xxxx","SEX","XXX@Gmail.com");    }}

使用@Module标识类型为module,并用@Provides标识提供依赖的方法

5.生成Component对象

有了提供依赖的组件(module),我们还需要将依赖注入到需要的对象中。连接提供依赖和消费依赖对象的组件被称为Injector。Dagger2中我们将这个对象其称为component。UserComponent代码如下

@Component(modules = UserModule.class)public interface UserComponent {    void inject(MainActivity mainActivity);}

可以看到,Component是一个使用@Component标识的Java interface。interface的inject方法需要一个消耗依赖的类型对象作为参数:通过 @Component 添加了一个 Module : UserModule,此外还有一个inject方法,其中的参数表示要注入的位置(先打个预防针,Component中的方法还可以起到暴露资源,实现Component中的“继承”的作用)

注意:这里必须是真正消耗依赖的类型MainActivity,而不可以写成其父类,比如Activity。因为Dagger2在编译时生成依赖注入的代码,会到inject方法的参数类型中寻找可以注入的对象,但是实际上这些对象存在于MainActivity,而不是Activity中。如果函数声明参数为Activity,Dagger2会认为没有需要注入的对象。当真正在MainActivity中创建Component实例进行注入时,会直接执行按照Activity作为参数生成的inject方法,导致所有注入都失败。(是的,我是掉进这个坑了。)

6.完成依赖注入

最后,我们需要在MainActivity中构建Injector对象,通过dagger得到我们的user对象

public class MainActivity extends AppCompatActivity {    @Inject    User user;    UserComponent component;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        component= DaggerUserComponent.builder().userModule(new UserModule()).build();        component.inject(this);        TextView textView=(TextView)findViewById(R.id.tv);        textView.setText("name:"+user.getName()+"\nsex:"+user.getSex()+"\nads:"+user.getAds());    }}

首先,使用@Inject标志被注入的对象User (注意User 不能为private),之后通过Dagger2生成的实现了我们提供的UserComponent 接口类DaggerUserComponent创建component,调用其inject方法完成注入。

至此,我们使用Dagger实现了最简单的依赖注入!

注意:这里的DaggerUserComponent不是我们自己创建的,是dagger自动在build时(可手动make project)创建的,后边的userModule也是更具你在Component设置的module对象生成的方法-如果不成功需先clean工程在make一遍


效果


源码

源码传送门-csdn-戳我


建议

如果你有任何的问题和建议欢迎加入QQ群告诉我!

更多相关文章

  1. Android(安卓)Handler消息处理机制详解
  2. Socket 通信原理 -- Android客户端和服务器以TCP&&UDP方式互通
  3. Android(安卓)进程间通信(IPC)-上
  4. android中四大引用的区别,强引用、软引用、弱引用和虚引用
  5. 制作一款简单的网络图片查看器
  6. Android中AsyncTask使用教程及源码分析
  7. Android(安卓)进阶:JSON数据与Java对象转换 - Gson的使用与实践
  8. Android中静态变量的生命周期
  9. 第三部分:Android(安卓)应用程序接口指南---第三节:应用程序资源--

随机推荐

  1. Android——最新LitePal使用
  2. fitsSystemWindows的理解与沉浸式状态栏
  3. [转]]Android 应用签名提权方法
  4. Android横竖屏总结
  5. 最受欢迎的文章汇总
  6. Android架构组件WorkManager详解
  7. android 悬浮窗教程
  8. Android(安卓)使用模拟位置(支持Android(
  9. Android基础知识之Manifest文件的组织结
  10. Android图片缩放总结及比较