在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就被注入了。