美文网首页
史上最适合新手的Dagger2教程(二)对象注入

史上最适合新手的Dagger2教程(二)对象注入

作者: Eternity岚 | 来源:发表于2018-07-27 09:07 被阅读0次

    Dagger2系列教程目录:

    史上最适合新手的Dagger2教程(一)基本注入

    史上最适合新手的Dagger2教程(二)对象注入

    史上最适合新手的Dagger2教程(三)模型与单例

    史上最适合新手的Dagger2教程(四)带参注入

    史上最适合新手的Dagger2教程(五)命名、限定与延时加载

    0.检查作业

    对答案了对答案了,后面那排睡觉的,起来做笔记了!

    杠精类:

    public class GangJing {
         @Inject
        public GangJing() {
        }
        public void gang(Activity activity) {
            Toast.makeText(activity, "这抠脚大汉天天卖萌", Toast.LENGTH_SHORT).show();
        }
    }
    

    注入器:

    注入器和上节课写的是一样的,不需要修改~

    @Component
    public interface MainActivityComponent {
        void inject(MainActivity mainActivity);
    }
    

    注入和调用:

    public class MainActivity extends AppCompatActivity {
         @Inject
        GangJing gangJing;
         @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            DaggerMainActivityComponent.create().inject(this);
            gangJing.gang(this);
        }
    }
    

    那么这节课我们基于上节课的作业继续讲解Dagger2.

    · 对象注入

    有时候我们的项目,需要创建A和B两个对象,其中B对象需要用到A的实例,如:

            A a = new A();
            B b = new B(a);
    

    这个时候,我们就要用到Dagger2的对象注入了。

    我们把上节课的卖萌类拿过来:

    public class SellMoe {
        @Inject
        public SellMoe() {
        }
         public String sellMoe() {
            return "赶紧卖了个大萌";
        }
    }
    

    然后改造一下作业里的杠精类:

    在内部声明一个卖萌类对象,在构造方法中传入它;

    然后添加一个方法看它卖萌(lookAtHim),调用卖萌类的方法。

    public class GangJing {
         //新增一个卖萌对象
        SellMoe sellMoe;
         //修改构造方法,传入卖萌对象
        public GangJing(SellMoe sellMoe) {
            this.sellMoe = sellMoe;
        }
         //添加一个调用卖萌对象的方法
        public String lookAtHim() {
            return sellMoe.sellMoe();
        }
         public void gang(Activity activity) {
            Toast.makeText(activity, "这抠脚大汉天天卖萌", Toast.LENGTH_SHORT).show();
        }
    }
    

    先不使用Dagger2:

    public class MainActivity extends AppCompatActivity {
         SellMoe sellMoe;
        GangJing gangJing;
         @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            TextView tv = findViewById(R.id.tv);
             //关键代码
            sellMoe = new SellMoe();
            gangJing = new GangJing(sellMoe);
    
            tv.setText(gangJing.lookAtHim());
            gangJing.gang(this);
        }
    }
    

    运行一下:


    要把SellMoe注入到GangJing里面去,只要在传入SellMoe的构造方法上加上@Inject就好:

    public class GangJing {
    
        SellMoe sellMoe;
    
        @Inject
        public GangJing(SellMoe sellMoe) {
            this.sellMoe = sellMoe;
        }
        public String lookAtHim() {
            return sellMoe.sellMoe();
        }
        public void gang(Activity activity) {
            Toast.makeText(activity, "这抠脚大汉天天卖萌", Toast.LENGTH_SHORT).show();
        }
    }
    

    Step2:注入对象

    注入器(@Component)依然使用作业里的注入器,无需修改~

    直接在MainActivity里调用就OK:

    public class MainActivity extends AppCompatActivity {
         //注意这里没有声明SellMoe对象!
        @Inject
        GangJing gangJing;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
             //注入对象
            DaggerMainActivityComponent.create().inject(this);
            
            TextView tv = findViewById(R.id.tv);
            tv.setText(gangJing.lookAtHim());
            gangJing.gang(this);
        }
    }
    

    注意这里没有声明SellMoe对象,但是运行一下,发现并没有爆出空指针异常,

    这说明Dagger2已经自动帮我们把SellMoe给注入到了GangJing类里了,厉害吧~

    这就是Dagger2厉害到不行的智能对象注入,它在你用@Inject标记GangJing的构造方法的时候,就已经帮你创建好SellMoe对象了:

        @Inject
        public GangJing(SellMoe sellMoe) {
            this.sellMoe = sellMoe;
        }
    

    基于此功能,使用Dagger2开发的项目,在构造方法被修改时无需修改调用处的代码,而且可以避免几乎所有的空指针

    有点开始懵逼了?那我用类比的方式说明一下:

    @Inject
    Object obj;
    

    这个代码,相当于:

    Object obj = new Object();
    

    而这个代码:

    ObjectA objA; 
    @Inject
    public ObjectB(ObjectA objA){
        this.objA = objA;
    }
    

    则相当于:

    ObjectA objA; 
    public ObjectB(ObjectA objA){
        this.objA = new ObjectA();
    }
    

    把@Inject注解理解成new操作,是不是就好理解了~

    2.注意事项

    值得一提的是,Dagger2在@Inject注入的时候,每次都会new一个对象

    比如我们给SellMoe加上一个字段id:

    public class SellMoe {
    
        public int id;
    
        @Inject
        public SellMoe() {
        }
        public String sellMoe() {
            return "赶紧卖了个大萌";
        }
    }
    

    在调用lookAtHim的时候打印一下id:

        public String lookAtHim() {
           Log.e("GangJingSellMoeID", sellMoe.id + ""); 
           return sellMoe.sellMoe();
        }
    

    在MainActivity中同样注入一个SellMoe对象,给它的id赋值为1:

    public class MainActivity extends AppCompatActivity {
        @Inject
        SellMoe sellMoe;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            DaggerMainActivityComponent.create().inject(this);
            sellMoe.id = 1;
            Log.e("MainSellMoeID", sellMoe.id + "");
    

    再执行一次代码:


    看到了吗,他们是两个不一样的卖萌类~

    那么如果需要用到单例怎么办呢?

    且听下回分解~

    相关文章

      网友评论

          本文标题:史上最适合新手的Dagger2教程(二)对象注入

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