Dagger2入门初探

1:什么是Dagger2 ?

简单的说它是DI(动态注入)框架,在降低代码依赖耦合方面效果显著。现由Google在维护。

2:如何使用Dagger2 ?
配置:
在项目build.gradle(Project:xxx)中添加如下代码:

dependencies {
      classpath 'com.android.tools.build:gradle:2.1.0'
      //添加apt插件
      classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
  }

在build.gradle(Module:app)中添加如下代码

apply plugin: 'com.android.application' 
//应用apt插件 
apply plugin: 'com.neenbedankt.android-apt'
 ... 
dependencies { ...
 compile 'com.google.dagger:dagger:2.4'
 compile 'org.glassfish:javax.annotation:10.0-b28' 
... }

在引入butterknife新版后之后,以上配置会提示警告,应改为以下:
项目build.gradle(Project:xxx)中移除:
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
build.gradle(Module:app)中移除:
apply plugin: 'com.neenbedankt.android-apt'

3:Dagger2 的使用样子
大体使用思路是这个样子的(基于MVP模式,不明白MVP的看谷歌官方去 : google mvp demo):

MVP接口:

public interface MyContract {
    interface View{
        void show(Object o);
    }

    interface Presenter{
        void loadData(String pram);
    }
}
public class MyPresenter implements MyContract.Presenter {
    private MyContract.View view;

    @Inject  // <=  这里是使用Dagger2时的注解,后面会讲到
    public MyPresenter(MyContract.View view){
        this.view = view;
    }

    @Override
    public void loadData(String pram) {
        view.show("test");
    }
}

测试activity:

public class TestActivity extends AppCompatActivity implements MyContract.View {

    @BindView(R.id.btn)
    Button btn;
    @BindView(R.id.tvInfo)
    TextView tvInfo;

    @Inject
    MyPresenter presenter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test);
        ButterKnife.bind(this);

        DaggerMyComponent.builder().myModel(new MyModel(this)).build().inject(this);

    }

    @OnClick(R.id.btn)
    public void onViewClicked() {
        presenter.loadData("test");
    }

    @Override
    public void show(Object o) {
        tvInfo.setText("返回值");
    }
}

Module类(生成依赖):

@Module   //Dagger2 注解
public class MyModel {
    MyContract.View view;
    public MyModel(MyContract.View view){
        this.view = view;
    }

    @Provides
    public MyContract.View myView(){
        return view;
    }

    @Provides
    public OkHttpClient provideOkHttpClient() {
        OkHttpClient okhttpClient = new OkHttpClient.Builder()
                .connectTimeout(30, TimeUnit.SECONDS)
                .build();
        return okhttpClient;
    }

    @Provides
    public Retrofit provideRetrofit(OkHttpClient okhttpClient) {
        Retrofit retrofit = new Retrofit.Builder()
                .client(okhttpClient)
                .baseUrl("https://api.github.com")
                .build();
        return retrofit;
    }

}

Component类(提供依赖)

@Component(modules = MyModel.class)
public interface MyComponent {
    void inject(TestActivity activity);
}

1:创建类用来提供依赖(使用@Module注解,并将返回依赖的方法使用@Provides注解)
2:创建Component接口,并用@Component(modules = MyModel.class) 标识该类,其中MyModel就是上面@Module注解的类。
3:在Activity中,用@Inject标识要使用的依赖,同时依赖中的构造方法也用@Inject 标识(如果有构造方法的话,不然也可以在Module中创建生成其他依赖的方法)
4:重建项目,会生成Dagger开头的Component类。
5:用生成Dagger开头的Component类初始化依赖,DaggerMyComponent.builder().myModel(new MyModel(this)).build().inject(this); 初始化依赖。
6:使用依赖。

  • @Inject 带有此注解的属性或构造方法将参与到依赖注入中,Dagger2会实例化有此注解的类
  • @Module 带有此注解的类,用来提供依赖,里面定义一些用@Provides注解的以provide开头的方法,这些方法就是所提供的依赖,Dagger2会在该类中寻找实例化某个类所需要的依赖。
  • @Component 用来将@Inject和@Module联系起来的桥梁,从@Module中获取依赖并将依赖注入给@Inject

activity中用@Inject注解MyPresenter 说明MyPresenter 需要注入到activity中,使用@Inject时,不能用private修饰符修饰类的成员属性。进入MyPresenter 发现其构造函数也被@Inject注解,这样当Dagger2扫描到注解时会进入其构造函数,如果构造函数也被注解,那么会自动完成注入即初始化。
但依赖和他的构造函数是怎么建立其联系的呢?就是Component,Component是一个接口或者抽象类,用@Component注解标注,rebuild项目之后会自动生成Dagger开头的Component类(其实DaggerComponent就是实现了我们自己定义的Component)。
然后初始化依赖,如下:

DaggerMyComponent.builder().myModel(new MyModel(this)).build().inject(this);

通过new MyModel(this)将view传递到MyModel里,然后MyModel里的myView()方法返回这个View,当去实例化MyPresenter时,发现构造函数有个参数,此时会在MyModel里查找提供这个依赖的方法,将该View传递进去,这样就完成了presenter里View的注入。

你可能感兴趣的:(技术篇)