上一篇介绍了@inject 标签的使用,只要我们在类的构造函数上声明了该标签,Dagger2就会在适当的时候调用该构造函数。
@Component作为容器,注册了需要使用容器中实例的对象。所以当我们使用一个类的时候,我们完全不需要new 的方式创建对象。
但是当类是我们自己写的时候可以使用@inject来让Dragger来帮我们实例化,但是如果是第三方提供的服务,比如okhttp,我们没有办法修改他人写的代码,这个时候我们就不能在使用@inject标签了。那我们该怎么办?
文章重点:
1)@Module是什么?
2)@Provides是什么?
第一部分:@Module是什么?
@Module是什么意思呢 @Module是和@Component配合使用的意思就是告诉注入器,如果你在实例化对象的时候,没有找到合适的构造函数,你就来我这里找,@Module通常标注一个类,该类里面可以实例化各种类,Component在注入对象的时候先去Module中找,如果找不到就会检查所有被@Inject标注的构造函数;
第二部分:@Provides是什么?@Provides 标签是放在@Module 注释下的类里方法上,告诉Dragger2我这个方法可以实例化对象。
第三部分:实例教程
首先我们有个第三方的类(无法修改他的代码)
/**
* Created by malei on 2018/3/20.
* 假设这个类不可以注解,因为是第三方源码库
*/
public class MainPresenter {
private final String mTool;
public MainPresenter(String tool){
mTool = tool;
}
public String getTool(){
return mTool;
}
}
如果我们想要使用这个类里的方法,那么我们就要有个专门实例化这些对象的类
/**
* Created by malei on 2018/3/20.
*/
@Module //专门做实例化处理的类
public class ActivityMoudle {
/**
* 获取实例
* @return
* @Provide 用来标注一个方法,告诉注入器,我标注的方法你可以用来提供实例;
* @Singleton 顾名思义,标注该实例化的对象为单例
*/
@Provides
@Singleton
public MainPresenter getMainPresenter(){
return new MainPresenter("feiji");
}
}
我们发现我们对第三方源码什么都没有改动,只是增加了个中间类ActivityMoudle,这个类他通过@Provides 注释将一个个实例放入容器中。
这样我们可以直接使用了,如下:
@Inject
MainPresenter mMainPresenter;
--
tv.setText(user.getName()+" = "+mMainPresenter.getTool());
-------------------------------
实例:
目标类
public class B {
@Inject
public B() {
}
public String getName(){
return "BBBBBBB";
}
}
module类
@Module
public class AModule {
//单例获取
@Singleton
@Provides
A providesA(){
return new A();
}
}
component类
@Singleton
@Component(modules = AModule.class)
public interface AComponent {
void inject(NewActivity act);
}
activity
public class NewActivity extends AppCompatActivity {
@Inject
A a1;
@Inject
A a2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_new);
//实例化component对象
AComponent component = DaggerAComponent.builder().aModule(new AModule()).build();
//注入
component.inject(this);
//single单例只适用于一个component,也就是说下一个activity中又是不同的对象了
Log.e("---------",a1.toString()+" "+a2.toString());
}
}
打印结果为:
com.iwith.dagger.xinde.A@d1f1395 com.iwith.dagger.xinde.A@d1f1395
注意点:
1:module中需要添加@singleton,component需要添加@singleton,不然会编译不过
2:这个只能在同个activity中,如果在另一个activity中的话,创建的实例就会使另一个了,不会是单例了,可见,@singleton只对一个component有效,即其单例所依赖component对象