Dagger2使用——结合MVP模式讲解

作者: wildma | 来源:发表于2017-07-22 18:18 被阅读44次

    更新:根据Dagger2官方最新配置,现在配置已经不需要添加android-apt插件了,所以配置更简单了。即在下文中说的Dagger2配置的第一步与第二步都可以省略了,第三步直接改成以下即可)。

        /*dagger2的配置*/
        annotationProcessor 'com.google.dagger:dagger-compiler:2.4'
        compile 'com.google.dagger:dagger:2.4'
        compile 'org.glassfish:javax.annotation:10.0-b28'
    

    前言

    相信大部分人在使用mvp模式的时候都会同时用到Dagger2框架,因为Dagger2能非常完美的解决mvp模式中存在的V层与P层之间的耦合。所以下面介绍Dagger2的使用也会结合我上一篇文章中的mvp模式来讲解,还没看上一篇文章的可以先去看看—— 带你通俗易懂的理解——Android中的MVC与MVP

    Dagger2是什么?

    Dagger2是一个在Android 和 Java中使用的依赖注入框架,现在由Google维护,是基于Dagger的基础上开发的,Dagger是由square开发的。Dagger2最大的作用就是解耦,例如ClassA中需要用到ClassB中的某个方法,但是又不想在ClassA中通过new的方式实例化ClassB,这时候Dagger2就很好的解决了这个问题,Dagger2可以在ClassA中通过依赖注入的方式实例化ClassB,从而达到ClassA与ClassB的解耦。

    Dagger2配置

    1、 在项目的build.gradle中添加android-apt插件
    buildscript {
        repositories {
            jcenter()
        }
        dependencies {
            classpath 'com.android.tools.build:gradle:2.2.3'
            //android-apt 插件
            classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
    
        }
    }
    
    2、在app的build.gradle中添加apt插件的使用
    //apt插件的使用
    apply plugin: 'com.neenbedankt.android-apt'
    
    android {
        ...
    }
    
    dependencies {
      ...
    }
    
    3、在app的build.gradle中添加Dagger2的依赖
    ...
    
    android {
     ...
    }
    
    dependencies {
        //dagger2的配置
        compile 'com.google.dagger:dagger:2.4'
        apt 'com.google.dagger:dagger-compiler:2.4'
        compile 'org.glassfish:javax.annotation:10.0-b28'
    }
    

    Dagger2使用

    经过上面的配置就可以在项目中使用Dagger2了,这里举的例子是基于我上篇mvp文章的基础上的,还没看上一篇文章的可以先去看看—— 带你通俗易懂的理解——Android中的MVC与MVP。该Demo中V层中的Activity如下:

    public class UserInfoActivity extends AppCompatActivity implements UserInfoView {
    
        private TextView    mTvName;
        private ProgressBar mPbLoading;
        UserInfoPresenter mUserInfoPresenter;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            //find view
            mTvName = (TextView) findViewById(R.id.tv_name);
            mPbLoading = (ProgressBar) findViewById(R.id.pb_loading);
    
            //init
            mUserInfoPresenter = new UserInfoPresenter(this);
        }
        ...
    }
    

    也就是Activity中使用new的方式实例化Presenter,这样就导致V层与P层耦合了,所以下面我就使用Dagger2将它们解耦。

    先看看几个注解的概念:

    • Module:在这里实例化目标类(例子中就是UserInfoActivity类)需要依赖的对象。

    • Provides:标注一个方法,该方法是用来提供实例化对象给目标类的。

    • Inject:标注实例化对象

    • Component:作为Module与目标类之间的桥梁。

    使用步骤:
    1、创建带有@Module注解的类,并利用@Provides标注一个方法用来提供实例化对象给目标类。

    @Module //实例化目标类需要依赖的对象
    public class UserInfoActivityModule {
    
        UserInfoActivity mActivity;
    
        public UserInfoActivityModule(UserInfoActivity activity) {
            mActivity = activity;
        }
    
        @Provides //该方法是用来提供实例化对象给目标类的
        UserInfoPresenter provideUserInfoPresenter() {
            return new UserInfoPresenter(mActivity);
        }
    }
    

    2、创建带有@Component的接口,将它作为Module与目标类之间的桥梁。

    @Component(modules = UserInfoActivityModule.class) //作为Module与目标类之间的桥梁
    public interface UserInfoActivityComponent {
    
        /**
         * 定义注入的方法
         * @param activity
         */
        void inject(UserInfoActivity activity);
    }
    

    3、标注实例化对象,并将Module与目标类联系起来。
    注意:DaggerUserInfoActivityComponent是Rebuild项目后根据定义的Component的类名自动生成的,所以这里先要Rebuild一下项目再使用。

    public class UserInfoActivity extends AppCompatActivity implements UserInfoView {
        @Inject //标注实例化对象
        UserInfoPresenter mUserInfoPresenter;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            ...
            //将Module与目标类联系起来
            DaggerUserInfoActivityComponent
                    .builder()
                    .userInfoActivityModule(new UserInfoActivityModule(this))
                    .build()
                    .inject(this);
        }
    ...
    }
    

    通过上面的三步其实就只实现了UserInfoActivityModule = new UserInfoActivityModule(this),看起来是复杂了许多,但是它非常完美的解决了mvp模式中存在的V层与P层之间的耦合。就好比使用mvp比使用mvc多了很多代码,但大家还是会使用mvp模式一样的道理。

    Demo地址:MVP-Pattern

    相关文章

      网友评论

        本文标题:Dagger2使用——结合MVP模式讲解

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