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注意事项,不需要单例的话不要纠结这个使用,这样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相互依赖使用,注意他们的区别:


如果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的使用灵活性比前面那种用法差一些。

上一篇下一篇

猜你喜欢

热点阅读