一、配置:
1.1 在Project的gradle脚本中配置
dependencies {
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
}
1.2在Module的gradle脚本中配置
apply plugin: 'com.neenbedankt.android-apt'
dependencies {
apt 'com.google.dagger:dagger-compiler:2.11'
compile 'com.google.dagger:dagger:2.11'
}
二、代码实现
2.1、使用@Inject和@Component实现依赖注入
2.1.1: 在实体类的构造方法中标注@Injecct,表示其提供依赖,代码如下:
package testdagger.com.xn.testdagger2.modle;
import android.util.Log;
import javax.inject.Inject;
/**
* Created by 贺谋昌 on 2017/8/1.
*/
public class Watch {
@Inject
public Watch() {
}
public void work() {
Log.e("Watch", "Dagger2 watch is work");
}
}
2.1.2:创建注入器,即提供依赖和目标类之前的桥梁,是一个用@Conponent标注的接口
代码如下:
package testdagger.com.xn.testdagger2.component;
import dagger.Component;
import testdagger.com.xn.testdagger2.MainActivity;
/**
* Created by 贺谋昌 on 2017/8/1.
*/
@Component
public interface MainActivityComponent {
void inject(MainActivity activity);
}
其创建的方法中传入的参数为目标类的实体
2.1.3
在目标类中进行注入,并标注依赖注入的实体类
public class MainActivity extends Activity {
@BindView(R.id.btn)
Button btn;
@Inject
Watch watch;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
DaggerMainActivityComponent.create().inject(this);
}
@OnClick(R.id.btn)
public void onViewClicked() {
watch.work();
}
}
DaggerMainActivityComponent这个类是在component类完成之后进行reBuild后自动生成的类。
2.2、使用@Module和@Provides提供依赖
如果代码中使用了第三方的类库,那么目标类所需的依赖是无法进行标注的,因为无法更改实体类的源代码,比如一个jar包,这时我们用@Module和@Provides提供依赖。
2.2.1、新建一个标注@Module的类,并通过标注@Provides的方法返回实体类的对象,代码如下:
/**
* Created by 贺谋昌 on 2017/8/1.
*/
@Module
public class GsonModule {
@Provides
public Gson getGson() {
return new Gson();
}
}
2.2.2、使用已经创建的component来管理Module,只要在类名处标注上管理的是哪个Module即可,代码如下:
**
* Created by 贺谋昌 on 2017/8/1.
*/
@Component(modules = GsonModule.class)
public interface MainActivityComponent {
void inject(MainActivity activity);
}
2.2.3、在目标类中注入,并标注要使用的实体类,代码如下:
public class MainActivity extends Activity {
@BindView(R.id.btn)
Button btn;
@Inject
Watch watch;
@Inject
Gson gson;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
DaggerMainActivityComponent.create().inject(this);
}
@OnClick(R.id.btn)
public void onViewClicked() {
watch.work();
JSONObject object = new JSONObject();
try {
object.put("name", "贺贺");
object.put("age", 24);
Man man = gson.fromJson(object.toString(), Man.class);
Log.e("MainActivity", man.getName());
} catch (JSONException e) {
e.printStackTrace();
}
}
}
2.3、如果要注入的对象是抽象的则不能用@Inject来提供依赖,这时要用@Module,案例如下:
Engine是一个抽象类
public abstract class Engine {
public abstract String work();
}
MyEngine是Engine的子类
public class MyEngine extends Engine {
@Override
public String work() {
return "MyEngine is working";
}
}
Car持有Engine的对象
public class Car {
Engine engine;
@Inject
public Car(Engine engine) {
this.engine = engine;
}
public String run() {
return engine.work();
}
}
2.3.1、在component中提供一个方法,给Engine提供实例
@Module
public class GsonModule {
@Provides
public Engine getEngine() {
return new MyEngine();
}
}
2.3.2在MainActivity中注入
“`
@Inject
Car car;
…
DaggerMainActivityComponent.create().inject(this);
….
Log.e(“MainActivity”, car.run() );
### 2.4、@Name和Qualifier的基本使用
如果@Inject标注的多个构造或是@Provides标注的方法返回的是同一种类型的值,那么程序就不知道使用哪一个来提供依赖,这时就会报错,我们就可以使用@Qualifier来标注我们要使用的是哪一个,@Name是@Qualifier的一种实现。案例如下:
如果Engine的子类有两个,除了MyEngine之外还有HerEngine,在Module中返回的Engine的实例的方法中,有两个方法,一个返回MyEngine一个返回HerEngine,这时我们就要标注好哪个方法返回哪个实例,并且目标类需要哪个实例,可以用@name(字符串)也可以自定义Qualifier,示例代码如下:
//首先定义两个自定义的Qualifier
@Qualifier
@Retention(RetentionPolicy.RUNTIME)
public @interface My {
}
….
….
@Qualifier
@Retention(RetentionPolicy.RUNTIME)
public @interface Her {
}
….
//在Module中标注好,哪个方法对应的哪个类的实例
@Provides
@My
public Engine getEngine() {
return new MyEngine();
}
@Provides
@Her
public Engine getHerEngine() {
return new HerEngine();
}
// 标注好目标类需要哪个实例
public class Car {
Engine engine;
@Inject
public Car(@Her Engine engine) {
this.engine = engine;
}
public String run() {
return engine.work();
}
}
使用@Name来标注则更为简单
@Provides
@Named(“My”)
public Engine getEngine() {
return new MyEngine();
}
@Provides
@Named("Her")
public Engine getHerEngine() {
return new HerEngine();
}
//在需要依赖的类中同样使用@Name标注好
public class Car {
Engine engine;
@Inject
public Car(@Named("Her") Engine engine) {
this.engine = engine;
}
public String run() {
return engine.work();
}
}
“`