[置顶] 分享一下Dagger2的使用经验

一、 Gradle配置

在project的gradle脚本内插入插件依赖:

buildscript { repositories { jcenter() }
    dependencies { classpath 'com.android.tools.build:gradle:1.3.0' // Add plugin classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8' }
}

在module的gradle插件中引入插件
首先引入apt插件(Dagger2的原理是在编译时注入代码)

apply plugin: 'com.neenbedankt.android-apt'

然后在dependencies里面添加依赖,现在的最新版本是2.0.2

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.1.1'
    compile 'com.android.support:design:23.1.1'

    compile 'com.google.dagger:dagger:2.0.2'
    apt 'com.google.dagger:dagger-compiler:2.0.2'
    compile 'org.glassfish:javax.annotation:10.0-b28'
}

最后一个依赖是javax注解的依赖,标准版本的JDK 1.7以上版本是直接有这个库的,但是Google在一开始就只提供了有限的javax的支持(Oracle的API版权)。

二、基本概念

理解Dagger2在一开始是很难的,首先你得需要理解依赖注入的概念和为什么需要依赖注入。如果你还不是很理解也没关系,接下来的这个例子会帮助你理解。

@Inject(注入):使用这个注解是告诉Dagger当前申明的类或者属性需要被注入,Dagger会根据配置来提供它的一个实例。
@Module(模块):它申明Dagger在哪里可以找到依赖,可以把多个Module合并到一块向Component提供依赖。
@Provide(提供):这个注解在@Module里使用,定义申明的方法告诉Dagger我们是如何构造并提供Module申明的实例的。
@Component(组件):它是连接Inject和Module的容器,我们将写好的Module放入组件中,并且通过他向申明了Inject的类或者属性提供注入。
@Scope(作用域):它的作用是申明Dagger的实例的生命周期,接下来的例子会用到它。
@Qualifier(作用范围):

三、使用实例

Step 1:
申明一个组件

/** * Created by Hubert on 15/12/9. */
@Singleton
@Component(modules = AppModule.class)
public interface AppComponent {

    void inject(BaseActivity baseActivity);

    Context context();

    Preference preference();
}

我们用了一个@Singleton注解申明它为单例的,Preference是我自己定义个一个类,用来保存用户偏好。

/** * Created by Hubert on 15/12/9. */
public class Preference {

    private String name;

    private boolean enableSSL;

    public boolean isEnableSSL() {
        return enableSSL;
    }

    public void setEnableSSL(boolean enableSSL) {
        this.enableSSL = enableSSL;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

Step 2:
申明一个模块

/** * Created by Hubert on 15/12/9. */
@Module
public class AppModule {

    private final DemoApplication application;

    private final Preference preference;

    public AppModule(DemoApplication application, Preference preference) {
        this.application = application;
        this.preference = preference;
    }

    @Provides
    @Singleton
    Context provideApplicationContext() {
        return application;
    }

    @Provides
    @Singleton
    Preference providePreference() {
        return preference;
    }
}

这个模块申明将由它提供Preference,而Preference则在它的构造函数中传入。

Step 3:
为了解释程序的后面部分有必要给大家讲一下我们团队采用的项目MVP结构。
首先所有的Activity都会继承一个BaseActivity

/** * Created by Hubert on 15/12/9. */
public abstract class BaseActivity<T extends Presenter> extends AppCompatActivity {

    private T mPresenter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mPresenter = newPresenter();
    }

    /** * Provide your own presenter for this activity. * * @return Presenter of specific activity. */
    protected abstract T newPresenter();

    protected T getPresenter() {
        return mPresenter;
    }

}

大家只需要理解到newPresenter方法会在onCreate的时候调用就足够理解后面的内容了。

Step 4:
上面的AppComponent提供了一个全局的组件,下面我们将为某一个Activity提供一个组件:

/** * Created by Hubert on 15/12/9. */
@PerActivity
@Component(dependencies = AppComponent.class, modules = {MainActivityModule.class})
public interface MainActivityComponent {

    void inject(MainActivity mainActivity);

}

Dagger 2是支持Component的复用的,MainActivityComponent依赖于AppComponent,它会为MainActivityComponent提供Preference,后面会涉及到。

/** * Created by Hubert on 15/12/9. */
@Module
public class MainActivityModule {

    private final MainActivityViewer mViewer;

    public MainActivityModule(MainActivityViewer viewer) {
        this.mViewer = viewer;
    }

    @Provides
    @PerActivity
    MainActivityPresenter provideMainActivityPresenter(Preference preference) {
        return new MainActivityPresenter(mViewer, preference);
    }

}

MainActivityModule提供了MainActivityPresenter,他提供的方法里面会有一个Preference的参数,这个参数将会由Dagger自动注入,有兴趣的人可以去看看Dagger生成的源码。

/** * Created by Hubert on 15/12/9. */
public class MainActivityPresenter extends Presenter<MainActivityViewer> {

    private Preference mPreference;

    public MainActivityPresenter(MainActivityViewer viewer, Preference preference) {
        super(viewer);
        mPreference = preference;
    }


    public void showPreference() {
        getViewer().showToastMessage(mPreference.toString());
    }
}

MainActivityPresenter提供了showPreference()方法,它将调用Viewer接口的showToastMessage。

Step 5:
这里面所有的东西都在MainActivity中全部整合起来。
MainActivity中实现了newPresenter方法

    @Inject
    MainActivityPresenter presenter;

    @Override
    protected MainActivityPresenter newPresenter() {
        DaggerMainActivityComponent.builder()
                .appComponent(DemoApplication.getInstance().getAppComponent())
                .mainActivityModule(new MainActivityModule(this))
                .build().inject(this);
        return presenter;
    }

DaggerMainActivityComponent是一开始不存在的,当写完了MainActivityComponent后点击编译就会生成。
通过以上调用presenter就被注入了。

你可能感兴趣的:(Dagger2)