1、假如Module中没有使用Scope,如@Singleton,则Component的定义的时候可以没有Scope
如
@Component(modules = {AppModule.class})
public interface AppComponent {
Application getApplication();
}
@Module
public class AppModule {
private Application application;
public AppModule(Application application) {
this.application = application;
}
@Provides
public Application provideApplication() {
return application;
}
}
2、假如Module中有使用Scope,如@Singleton,而Component的定义的时候没有Scope,则会报错如:
@Component(modules = {AppModule.class})
public interface AppComponent {
Application getApplication();
}
@Module
public class AppModule {
private Application application;
public AppModule(Application application){
this.application=application;
}
@Provides
@Singleton
public Application provideApplication(){
return application;
}
}
这里Module里面使用了@Singleton而Component中没有,所以报错了。当我们在Component上面加上@Singleton错误消失3、然后我们看看Singleton对赋值的影响
Component
@Singleton
@Component(modules = {AppModule.class})
public interface AppComponent {
Application getApplication();
User getUser();
User3 getUser3();
}
注意这里有getUser、getApplication等方法,如果这里不写的话,dagger自动生成的DaggerComponent中没有相应的provider,这个好像仅限于在application注册的Component,而在Activity中注册的不需要。
Module
@Module
public class AppModule {
private Application application;
public AppModule(Application application) {
this.application = application;
}
@Provides
@Singleton
public Application provideApplication() {
return application;
}
@Provides
@Singleton
User provideUser() {
User user = new User();
user.setId("1");
user.setName("hello world");
return user;
}
@Provides
User3 provideUser3() {
User3 user = new User3();
user.setId("1");
user.setName("hello world");
return user;
}
}
我们一个设置Singleton,一个没有,然后在两个Activity中注入
首先是第一个Activity
public class MainActivity extends BaseActivity {
@Inject
User user20;
@Inject
User user21;
@Inject
User3 user32;
@Inject
User3 user31;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.inject(this);
Intent i = new Intent(this, MainActivity2.class);
startActivity(i);
}
@Override
protected void setupActivityComponent(AppComponent appComponent) {
DaggerMainActivityComponent.builder()
.appComponent(appComponent)
.mainActivityModule(new MainActivityModule(this))
.build()
.inject(this);
}
}
@ActivityScope
@Component(modules = {MainActivityModule.class},dependencies = AppComponent.class)
public interface MainActivityComponent {
MainActivity inject(MainActivity mainActivity);
}
public class MainActivityModule {
private MainActivity mainActivity;
public MainActivityModule(MainActivity mainActivity) {
this.mainActivity = mainActivity;
}
@Provides
@ActivityScope
MainActivity provideMainActivity() {
return mainActivity;
}
}
这里注意dependencies 不能是Module,如果改成Module的话会提示providerUser访问权限问题,但当我们改为public后会发现provider每次实例化都会调用该方法,实例化一个新的变量。这里如果dependencies 是Component,我们的MainActivityComponent 的Scope不能是Singleton,他依赖的Module也不能是Singleton,而且一个Component的Scope只能有一个。
我们调试可以看到各个变量的值
可以看到User的两个变量值是一样的,而User3不一样,可以看到Singleton起作用了
然后这里我们会跳转到MainActivity2
public class MainActivity2 extends BaseActivity {
@Inject
User user20;
@Inject
User user21;
@Inject
User3 user32;
@Inject
User3 user31;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
ButterKnife.inject(this);
}
@Override
protected void setupActivityComponent(AppComponent appComponent) {
DaggerMainActivityComponent2.builder()
.appComponent(appComponent)
.mainActivityModule2(new MainActivityModule2(this))
.build()
.inject(this);
}
}
这里跟MainActivity代码基本是一样的我们看下他们的值
User还是前面的值,而User3都变化了
所以以通过在Application中提供的Singleton类型的provider起到了全局值唯一的作用。
我们看下User 的provider的实现
从这里可以看到User是从appComponent中去取的
userProvider是通过ScopedProvider去创建的,最终调用的get
这里可以看到我们是通过单实例实现的,这里provider是唯一的,provider里面提供的实例也是唯一的,所以整个应用是唯一的,也只有在Application中定义的Component才是全局唯一的,而我们通过自定义的Scope由于Provider是在属于的Component中初始化的,所以只在当前的Component是唯一的。在其他Component又会重新初始化provider.
4、然后我们自定义一个Scope MyScope
@Scope
@Retention(RUNTIME)
public @interface MyScope {
}
@MyScope
@Component(modules = {MainActivityModule.class}, dependencies = CommonModule.class)
public interface MainActivityComponent {
MainActivity inject(MainActivity mainActivity);
}
@Module
public class CommonModule {
@Provides
@MyScope
User2 provideUser2() {
return new User2();
}
}
@Module
public class MainActivityModule {
private MainActivity mainActivity;
public MainActivityModule(MainActivity mainActivity) {
this.mainActivity = mainActivity;
}
@Provides
@MyScope
MainActivity provideMainActivity() {
return mainActivity;
}
}
可以看到,在Activity内部,是同一个实例,在不同的activity是不同的实例
这里可以看到,他们的provider是不一样的,是各自在各自的Component中生成的,但是他们的provider都是通过ScopedProvider生成的,所以在同一个Activity中是一样的实例
这里我们换成Singleton也是一样的,因为生成了两个provider,只是在各自的Component是单实例的