1. 程式人生 > >Dagger2使用——結合MVP模式講解

Dagger2使用——結合MVP模式講解

更新:根據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模式一樣的道理。