Android_Dagger2原理与入门使用

转载请注明出处:http://my.csdn.net/Android___vv


Dagger2简称依赖注入,是实现程序解耦的一种方式

大致原理:在程序中,一个对象中需要另一个对象的实例,实例对象的方式不再该对象中通过new创建,而是调用者外部创建实例化对象,通过一定的方式进行传入

上面所说的外部,指的就是一个存放对象的容器,具体需要哪个实例时,就从这个容器中取就行了。那么,现在类的实例和使用就不在有联系了,而是通过一个容器将他们联系起来。实现了解耦。这个容器,便是Dagger2


开始导入Dagger2的依赖

在工程的build.gradle文件中添加android-apt插件

 dependencies {

        classpath 'com.android.tools.build:gradle:2.1.0'
        // 添加android-apt 插件
        classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
    }
在app的中的 build.gradle 文件中添加配置

// 添加应用插件
apply plugin: 'com.neenbedankt.android-apt'
// dagger 2 的配置
    compile 'com.google.dagger:dagger:2.4'
    apt 'com.google.dagger:dagger-compiler:2.4'
    compile 'org.glassfish:javax.annotation:10.0-b28'// 添加java 注解库
以上两个配置就可以了,但如果你的Studio 升级到3.0之后就会遇到

Error:android-apt plugin is incompatible with the Android Gradle plugin.  Please use 'annotationProcessor' configuration instead.
解决办法: Studio升级到3.0之后原来的配置方式apt与最新版本Gradle已经不兼容,推荐使用annotationProcessor

只需要添加这三个依赖就可以   工程的build.gradle与app的build.gradle插件可不用添加

 // dagger 2 的配置
    compile 'com.google.dagger:dagger:2.4'
    annotationProcessor 'com.google.dagger:dagger-compiler:2.4'
    compile 'org.glassfish:javax.annotation:10.0-b28'// 添加java 注解库

Dagger2的使用

Module实例化部分(容器)

@Module //提供依赖对象的实例
public class MainModule {
    @Provides
        //标明该方法提供依赖对象
    Person providerPerson(){
        return new Person();
    }
}
  Component沟通部分     桥梁
@Component(modules = MainModule.class)  // 作为桥梁,沟通调用者和依赖对象库
public interface MainComponent {
    //定义注入的方法
    void inject(MainActivity activity);
}
需要实例化对象的类中

public class MainActivity extends AppCompatActivity {

    @Inject  //标明需要注入的对象
    Person person;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // 构造桥梁对象
        MainComponent component = DaggerMainComponent.builder().mainModule(new MainModule()).build();
        //注入
        component.inject(this);
    }
}

@Singleton 单例注解

   举个例子:对于同一个对象,需要注入两次  

public class MainActivity extends AppCompatActivity {

    @Inject  //标明需要注入的对象
    Person person;
    @Inject
    Person person2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // 构造桥梁对象
        MainComponent component = DaggerMainComponent.builder().mainModule(new MainModule()).build();
        //注入
        component.inject(this);
        //调用方法
        person.get();
        //打印地址
        Log.i("TAG","person  = "+ person.toString());
        Log.i("TAG","person2 = "+ person2.toString());
    }
}
    下面是打印结果

01-10 18:45:41.623 6069-6069/com.example.dagger2 I/TAG: person  = com.example.dagger2.Person@4a7f7928
01-10 18:45:41.623 6069-6069/com.example.dagger2 I/TAG: person2 = com.example.dagger2.Person@4a7f79c8
   打印出的地址不同,也就是我们创建了两个对象,这时就用到了单利注解

  Module中在提供实例化对象的方法上添加@Singleton注解

@Singleton//单利注解
@Component(modules = MainModule.class)  // 作为桥梁,沟通调用者和依赖对象库
public interface MainComponent {
    //定义注入的方法
    void inject(MainActivity activity);
}
    MainComponent 也一样

@Singleton//单利注解
@Component(modules = MainModule.class)  // 作为桥梁,沟通调用者和依赖对象库
public interface MainComponent {
    //定义注入的方法
    void inject(MainActivity activity);
}
   再看一下打印结果

01-10 18:45:41.623 6069-6069/com.example.dagger2 I/TAG: person  = com.example.dagger2.Person@4a7f7928
01-10 18:45:41.623 6069-6069/com.example.dagger2 I/TAG: person2 = com.example.dagger2.Person@4a7f7928
  两个对象地址一样,只创建了一个对象,需要注意的是  @Singleton 只对一个 Component 有效,即其单例所依赖 Component 对象


需要参数的实例化对象


需要实例化的类,构造方法需要传入一个集合

public class Person {

    private List list;

    public Person(List list) {
        this.list = list;
    }

    public void get(){
        Log.i("TAG",list.size()+"");
    }
}
Module中
@Module //提供依赖对象的实例
public class MainModule {

    private List mlist;

    public MainModule(List list) {
        this.mlist = list;
    }

    @Provides
    List providesList(){
        return mlist;
    }


    @Provides//标明该方法提供依赖对象
    @Singleton//单利注解
    Person providerPerson(List list){
        return new Person(list);
    }
}

  •    修改providerPerson方法,传入List集合。
    •    添加providesList(),用以提供List集合。

      •    从MainModule中根据返回值,找到providerPerson(List list)对象。
      •    发现其需要传入参数List,找到moudule中具有返回值为List的方法providesList()
    • 为什么要这么麻烦地再多写一个provideList()方法,因为解耦,如果使用了保存的对象,会导致下次List获取发生变化时,需要修改providerPerson(List list)中的代码。

Component中没有做改变

@Singleton//单利注解
@Component(modules = MainModule.class)  // 作为桥梁,沟通调用者和依赖对象库
public interface MainComponent {
    //定义注入的方法
    void inject(MainActivity activity);
}
使用

import javax.inject.Inject;

public class MainActivity extends AppCompatActivity {

    @Inject  //标明需要注入的对象
    Person person;
    @Inject
    Person person2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        List list = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            list.add("数据"+i);
        }
        // 构造桥梁对象
        MainComponent component = DaggerMainComponent.builder().mainModule(new MainModule(list)).build();
        //注入
        component.inject(this);
        //调用方法
        person.get();
    }
}
















你可能感兴趣的:(Android_Dagger2原理与入门使用)