美文网首页
Dagger2使用理解心得

Dagger2使用理解心得

作者: ztzt123 | 来源:发表于2018-02-26 17:10 被阅读0次

    Dagger2,是一个google的依赖注入框架,在项目中有使用,但一直不是很理解使用的过程,现在要做到的是,理解为什么要这么使用。
    在我们需要组合一个对象的的时候就需要手动new出该对象,但当我们需要修改这个对象的构造时,就需要对这个被组合的类进行修改,这样就耦合了。我们思考这样一个问题,可否实现这样一种方式,创建一个容器,当我们需要这个对象时,直接从容器中去取。而这个容器就是Dagger2要帮我们做的。
    使用Dagger2,我理解为有以下几个部分。
    1 调用者(被注入者)
    2 注入者 (注入的对象)
    3 实例化部分
    4 注入桥梁(将实例化的对象注入到调用者中)

    relative.png

    我个人的理解是这样的, 从右向左, 实例化部分会创建注入者的对象,先放在实例化部分备用,注入桥梁的作用是将对应的对象,从实例化部分中取出然后注入到调用者中去,实现对象的绑定。

    直接用例子 说明了:
    入过我们想在Activity中添加一个Presenter,正常情况下我们会在Activity中new出这个对象。

    public class MainPresenter {
        private MainView view;
        public MainPresenter(MainView view){
            this.view = view;
        }
        public void loadData(){
            view.setData();
        }
    }
    
      public class MainActivity extends AppCompatActivity implements MainView {
          MainPresenter mainPresenter;
          @Override
          protected void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              setContentView(R.layout.activity_main);
              mainPresenter = new MainPresenter(this);
              mainPresenter.loadData();
          }
    
          @Override
          public void setData() {
          }
      }
    

    现在的MainPresenter只有这一处使用,但如果多次使用的话,通过这样的方式,如果要修改多处创建的地方,所有的使用者和MainPresenter都存在直接的耦合关系。

    使用Dagger2注入的方式。

    方式一:实例化部分提供MainPresenter

      @Module
      public class MainModule {
          private final MainView mainView;
    
          public MainModule(MainView view) {
              mainView = view;
          }
          @Provides
          MainPresenter provideMainPresenter(){
              return new MainPresenter(mainView);
          }
      }
    

    @Module注解的部分对应实例化部分。

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

    @Component定义的部分对应桥梁。指定注入的对象MainActivity

    @Inject
    MainPresenter mainPresenter;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        DaggerMainComponent.builder()
                .mainModule(new MainModule(this))
                .build()
                .inject(this);
        mainPresenter.loadData();
    }
    

    在MainActivity中使用,需要添加 @Inject注解,并指定MainModule;

    方式二:Module提供MainView,实例化部分交由Dagger2创建

    @Module
    public class MainModule {
        private final MainView mainView;
        public MainModule(MainView view) {
            mainView = view;
        }
        @Provides
        MainView provideMainView() {
            return mainView;
        }
    }
    

    不同的部分就是我们provide的不是直接创建的MainPresenter而是mainView。

    @Inject
    public MainPresenter(MainView view){
        this.view = view;
    }
    

    这时在MainPresenter中的对应参数的构造添加 @Inject注解。使用时与方式一无异。

    方式三:通过注入桥梁直接返回对象实例

    确切的说 这个不能说是方式三,方式三可以与前两个方式组合使用。注入桥梁的定义方式不同。

    @Component(modules = MainModule.class)
    public interface MainComponent {
    MainPresenter getPresenter();
    }

    只要在Module中能找到合适的返回类型,或者在标记了@Inject的构造相匹配(参数也符合要求,能找到对应的参数,就可以通过桥梁直接获取对象实例。

    使用时:

      MainPresenter mainPresenter;
      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main);
          mainPresenter = DaggerMainComponent.builder()
                  .mainModule(new MainModule(this))
                  .build()
                  .getPresenter();
          mainPresenter.loadData();
      }
    

    直接获取对象实例,不需要使用@Inject注解,但不推荐这种方式,这样会降低注入代码的可读性。

    还需要再提到一个Lazy类
    Lazy类是实现懒加载,调用的时候才创建实例,通过Lazy对象实现,得到对象的实例使用get()方法。
    获取时包上Lazy。使用时先get。

      @Inject
      Lazy<MainPresenter> mainPresenter;
    
      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main);
          DaggerMainComponent.builder()
                  .mainModule(new MainModule(this))
                  .build()
                  .inject(this);
          mainPresenter.get().loadData();
      }
    

    就先到这吧

    相关文章

      网友评论

          本文标题:Dagger2使用理解心得

          本文链接:https://www.haomeiwen.com/subject/vniyxftx.html