美文网首页
Dagger使用

Dagger使用

作者: 双囍_小赵 | 来源:发表于2021-09-14 09:31 被阅读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的使用灵活性比前面那种用法差一些。

    相关文章

      网友评论

          本文标题:Dagger使用

          本文链接:https://www.haomeiwen.com/subject/racfgltx.html