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

2018-07-27  本文已影响0人  Eternity岚

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 + "");

再执行一次代码:


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

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

且听下回分解~

上一篇下一篇

猜你喜欢

热点阅读