美文网首页
Dagger2 入门

Dagger2 入门

作者: 竖起大拇指 | 来源:发表于2021-05-08 18:24 被阅读0次

    1.Dagger2的简单使用

    为什么需要使用Dagger2?
    通过Dagger2的目的是将程序分为三个部分。

    • 实例化部分:对象的实例化。类似于容器,将类的实例放在容器中
    • 调用者:需要实例化对象的类
    • 沟通桥梁:利用Dagger2中的一些API将两者联系。

    1.1.实例化部分(容器),在此处是Module

    @Module   //提供依赖对象的实例
    public class MainModule {
    
        @Provides // 关键字,标明该方法提供依赖对象
        Person providerPerson(){
            //提供Person对象
            return new Person();
        }
    
    
    }
    
    

    1.2 沟通部分Component

    @Component(modules = MainModule.class)  // 作为桥梁,沟通调用者和依赖对象库
    public interface MainComponent {
    
        //定义注入的方法
        void inject(MainActivity activity);
    
    }
    

    1.3 使用者Activity中调用

    public class MainActivity extends AppCompatActivity{
    
        @Inject   //标明需要注入的对象
        Person person;
    
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            // 构造桥梁对象
            MainComponent component = DaggerMainComponent.builder().mainModule(new MainModule()).build();
    
            //注入
            component.inject(this);
    
        }
    }
    

    看一下Person

    
    public class Person {
    
        public Person(){
            Log.i("dagger","person create!!!");
        }
    
    
    }
    

    我们来分析下调用过程:

    • 创建Component(桥梁),并调用注入方法。
    // 构造桥梁对象
            MainComponent component = DaggerMainComponent.builder().mainModule(new MainModule()).build();
    
            //注入
            component.inject(this);
    
    
    • 查找当前类中带有@Inject的成员变量。
    @Inject   //标明需要注入的对象
        Person person;
    
    • 根据成员变量的类型从Moudle中查找哪个有@Providers注解的方法返回值为当前类型。
     @Provides // 关键字,标明该方法提供依赖对象
        Person providerPerson(){
            //提供Person对象
            return new Person();
        }
    

    在使用过程出现了很多注解:

    • @Module:作为实例对象的容器。
    • @Provides:标注能够提供实例化对象的方法。
    • @Component:作为桥梁,注入对象的通道。
    • @Inject:需要注入的方法

    2. @Singleton 单例注解

    假如,对于同一个对象,我们需要注入两次,如下方式:

    public class MainActivity extends AppCompatActivity{
    
        @Inject
        Person person;
    
        @Inject
        Person person2;
    
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            // 构造桥梁对象
            MainComponent component = DaggerMainComponent.builder().mainModule(new MainModule()).build();
    
            //注入
            component.inject(this);
    
            // 打印两个对象的地址
            Log.i("dagger","person = "+ person.toString()+"; person2 = "+ person2.toString());
        }
    }
    

    看一下结果:

    person = com.mahao.alex.architecture.dagger2.Person@430d1620;
    person2 = com.mahao.alex.architecture.dagger2.Person@430d17c8
    

    可见两个对象不一致。也就是说创建了两个对象。
    可以在提供实例化对象的方法上添加@Singleton注解

    @Provides // 关键字,标明该方法提供依赖对象
        @Singleton
        Person providerPerson(){
    
            return new Person();
        }
    

    同时,对于MainComponent也需要添加注解,不添加则会无法编译

    @Singleton
    @Component(modules = MainModule.class)  // 作为桥梁,沟通调用者和依赖对象库
    public interface MainComponent {
        //定义注入的方法
        void inject(MainActivity activity);
    
    }
    

    此时在Log,会发现两个对象的地址一样,可见是同一个对象。

    那么不同的Activity之间,能否保持单例呢?

    创建一个新的Activity,代码如下:

    public class Main2Actvity extends AppCompatActivity {
    
        @Inject
        Person person;
    
    
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            // 构造桥梁对象
            MainComponent component = DaggerMainComponent.builder().mainModule(new MainModule()).build();
    
            //注入
            component.inject(this);
    
            Log.i("dagger","person = "+ person.toString());
        }
    }
    

    结果如下:

    person create!!!
     person = com.mahao.alex.architecture.dagger2.Person@4310f898; person2 = com.mahao.alex.architecture.dagger2.Person@4310f898
     person create!!!
     person = com.mahao.alex.architecture.dagger2.Person@43130058
    

    可见,@Singleton只对一个Component有效,即其单例所依赖Component对象.

    3.需要参数的实例化对象

    Person的构造方法发生了变化,需要传入一个Context,代码如下:

    public class Person {
    
        private Context mContext;
    
        public Person(Context context){
            mContext = context;
            Log.i("dagger","create");
        }
    
    }
    

    这样的话,我们需要修改MainModule

    @Module   //提供依赖对象的实例
    public class MainModule {
    
        private Context mContext;
    
        public MainModule(Context context){
            mContext = context;
        }
    
    
        @Provides
        Context providesContext(){
            // 提供上下文对象
            return mContext;
        }
    
        @Provides // 关键字,标明该方法提供依赖对象
        @Singleton
        Person providerPerson(Context context){
    
            return new Person(context);
        }
    
    }
    
    • 修改providerPerson方法,传入Context 对象。
    • 添加providesContext(),用以提供Context对象。

    看一下使用

    // 构造桥梁对象
            MainComponent component = DaggerMainComponent.builder().mainModule(new MainModule(this)).build();
    
            //注入
            component.inject(this);
    
    

    逻辑:

    • 根据@Inject注解,查找需要依赖注入的对象。
    • MainModule中根据返回值,找到providerPerson(Context context) 对象。
    • 发现其需要传入参数 Context,找到module中具有返回值为Context的方法providersContext().
    • 最后就成功的构建了实例化对象。
    注:在编写Module中,不能出现传入参数和返回参数一致的情况,会导致死循环。

    很容易理解,需要的和获取的是同一个方法,循环调用。

    相关文章

      网友评论

          本文标题:Dagger2 入门

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