Dagger使用
2021-09-14 本文已影响0人
双囍_小赵
Dagger使用之前导入:
//使用dragger
implementation 'com.google.dagger:dagger:2.4'
annotationProcessor 'com.google.dagger:dagger-compiler:2.4'
在Dagger中使用单例,不要使用Singleton,因为它是一个模板代码,使用自己定义的Scope。
下面Named也可以作为一个模板使用。
- Scope:就是类似单例使用
- Dependencies:用于两个Component相依赖
注:如果需要单例才会存在Scope注意事项,不需要单例的话不要纠结这个使用,这样Component和mudule以及定义的class都不需要定义Scope,也不需要标记@Scope注解
Scope&Dependencies连用的时候注意:
1.多个Component上面的Scope不能相同
2.没有Scope的组件不能取依赖有Scope的组件
如果需要使用到多个Scope,可以定义多个不同名的Scope注解类,一般大型项目中的Scope使用定义差不多最多也就4、5个不会太多。
/**
* Created by:zx
* on 9/9/21
* 这里定义的和原本的@Singleton注解类似,也就是自己写一个单例注解
**/
@Scope
@Documented
@Retention(RetentionPolicy.RUNTIME)
public @interface MyScope {
}
@Scope
@Documented
@Retention(RetentionPolicy.RUNTIME)
public @interface My2Scope {
}
在Component中使用MyScope和My2Scope:
//如果使用了dependencies依赖,使用单例的话,就直接用自己定义的@MyScope ,然后依赖的另外一个PresenterComponent里要使用不同的自定义的单例修饰@MyScope2
@MyScope
@Component(modules = {DataBaseModule.class},dependencies = {PresenterComponent.class})//这里注意依赖的是PresenterComponent
//由于di包中定义了另外一个Component,如果两个Component都需要在同一个Activity中使用,需要将两个结合,以上结合样子
public interface MyComponent {
//注入哪个类里就写哪个类,不要写泛型
//主Component写法
void injectMain(MainActivity activity);
void injectMain2(Main2Activity activity);
}
//由于这个是依赖于另外一个MyComponent所以单例的话就使用区别于MyComponent注解的另外一个自定义单例注解 My2Scope
@My2Scope
@Component(modules = {PresenterModule.class})
public interface PresenterComponent {
//如果是组合式Component使用,下面的语法就不能在用了
// void injet(MainSubActivity activity);
//这样使用 直接定义一个方法返回类型是Presenter
Presenter getPresenter();//子Component的写法
}
以上两个Component相互依赖使用,注意他们的区别:
- 在MyComponent中的@Component注解里加了dependencies=PresenterCompoent.class,作用是:让PresenterComponent依赖于主MyComponent。
- 它们接口里定义的方法方式不同,(主Component)一个写的添加注入方法,(副Component)一个使用自定义的类的构造方法。
如果Component使用了单例,那么和他连用的module和module类中使用的类都要用Scope修饰,如下代码:
@My2Scope//同PresenterComponent
@Module
public class PresenterModule {
@My2Scope
@Provides
public Presenter getPresenter() {
return new Presenter();
}
}
/**
* Created by:zx
* on 9/9/21
* 自定义的类,用于注入的类
**/
public class Presenter {
}
/**
* Created by:zx
* on 9/9/21
**/
@MyScope
@Module
public class DataBaseModule {
@MyScope
@Provides
public DataBaseObject dataBaseObject() {
return new DataBaseObject();
}
//module里可以有多个不同的方法
}
/**
* Created by:zx
* on 9/9/21
* 自定义的类,用于注入
**/
public class DataBaseObject {
}
在Activity中注入使用:
import android.os.Bundle;
import android.util.Log;
import androidx.appcompat.app.AppCompatActivity;
import com.zx.dagger_demo.MyApplication;
import com.zx.dagger_demo.R;
import com.zx.dagger_demo.component1.di.Presenter;
import com.zx.dagger_demo.component1.object.DataBaseObject;
import javax.inject.Inject;
public class Main2Activity extends AppCompatActivity {
@Inject
DataBaseObject dataBaseObject;
@Inject
Presenter presenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
//DaggerMyComponent是在定义了MyComponent build自动生成的类,可以查看build里的文件看到
// 下面用法:
// DaggerMyComponent.builder()
// .dataBaseModule(new DataBaseModule())
// .build()
// .injectMain2(this);
// Log.d("zx","dataBaseObject------"+dataBaseObject.hashCode());
//我们发现和不同的Activity打印的并不是同一个单例,可以自己试一下创建两个Activity注入, 所以此时我们如果想要同一个单例,就要在同一个地方进行DaggerMyComponent.builder()创建,因此我们定义在application中进行调用
//2021-09-09 14:52:34.487 5463-5463/com.zx.iocmode D/zx: ----190600968
//2021-09-09 14:52:34.487 5463-5463/com.zx.iocmode D/zx: ----17149601
//2021-09-09 14:52:34.487 5463-5463/com.zx.iocmode D/zx: ----17149601
//2021-09-09 14:52:34.698 5463-5463/com.zx.iocmode D/zx: 2------102658128
//改成下面这样调用,就会得到同一个对象
((MyApplication)getApplication()).getMyComponent().injectMain2(this);
Log.d("zx","2+dataBaseObject------"+dataBaseObject.hashCode());
Log.d("zx","2+presenter------"+presenter.hashCode());
}
}
Application中进行初始化创建:
/**
* Created by:zx
* on 9/9/21
* 测试dagger
**/
public class MyApplication extends Application {
private MyComponent myComponent;
@Override
public void onCreate() {
super.onCreate();
myComponent = DaggerMyComponent.builder()
.dataBaseModule(new DataBaseModule())
//依赖Component的创建
.presenterComponent(DaggerPresenterComponent.create())
.build();
}
public MyComponent getMyComponent() {
return myComponent;
}
}
以上是两个Component相互依赖使用案例。
相互依赖的Component还有另外一种方式使用:SubComponent
/**
* Created by:zx
* on 9/10/21
* 主Component
* 主Component引用子Component的变化
**/
@Component(modules = {MainModule.class})
public interface MainComponent {
//实现子Component
SubComponent sub();
}
/**
* Created by:zx
* on 9/10/21
* 副Component
* 副Component使用了@Subcomponent注解修饰
**/
@Subcomponent(modules = {SubMudule.class})
public interface SubComponent {
void injectMainActivity(MainSubActivity activity);
}
module的内容还是和之前差不多:
/**
* Created by:zx
* on 9/10/21
* 副module
**/
@Module
public class SubMudule {
@Provides
public SubObject subObject(){
return new SubObject();
}
}
/**
* Created by:zx
* on 9/10/21
* 主Module
**/
@Module
public class MainModule {
//Named表示标记,可以在使用的时候引用到哪个方法 ,可以用这个标记获取值,使用用法看Activity中的
@Named("key1")
@Provides
public MainObject mainObject(){
return new MainObject("zx","123");
}
@Named("key2")
@Provides
public MainObject mainObject1() {
return new MainObject("zx2", "12345");
}
}
Activity中使用:
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import com.zx.dagger_demo.R;
import com.zx.dagger_demo.component2.di.DaggerMainComponent;
import com.zx.dagger_demo.component2.di.obj.MainObject;
import com.zx.dagger_demo.component2.di.obj.SubObject;
import javax.inject.Inject;
import javax.inject.Named;
public class MainSubActivity extends AppCompatActivity {
@Named("key1")
@Inject
MainObject mainObject;
@Named("key2")
@Inject
MainObject mainObject2;
@Inject
SubObject subObject;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//不要忘记需要创建Component
DaggerMainComponent
.create()
.sub()
.injectMainActivity(this);
Log.d("zx","---------------mainObject:"+mainObject.getName()+" "+mainObject2.getName());
Log.d("zx","---------------subObject:"+subObject.hashCode());
//打印信息:获取到module中的定义的不同方法的值,Named用于区分定义的不同的方法
2021-09-10 18:31:38.418 9388-9388/com.zx.dagger_demo D/zx: ---------------mainObject: zx zx2
2021-09-10 18:31:38.418 9388-9388/com.zx.dagger_demo D/zx: ---------------subObject:190600968
}
}
如果想注入其他的类,就定义一个例如:User.class
/**
* Created by:zx
* on 9/13/21
* 如果想注入User这个类
**/
public class User {
String name;
String pwd;
public User(String name, String pwd) {
this.name = name;
this.pwd = pwd;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
}
在前面的SubModule中使用:
/**
* Created by:zx
* on 9/10/21
* 副module
**/
@Module
public class SubMudule {
@Provides
public SubObject subObject(){
return new SubObject();
}
//User使用
@Provides
public User user1(){
return new User("zx","qwe");
}
}
在Activity中使用直接加一个注入Inject:
@Inject
User user;
打印user:"+user.getName()+" "+user.getPwd()
-----user:zx qwe
*注:创建了Component后需要build一下,不然找不到DaggerMainComponent。
动态传参一般不太适合用Dagger。
SubComponent的使用灵活性比前面那种用法差一些。