Dagger的Scope注解代表的是作用域,通过实现自定义@Scope注解,标记当前生成对象的使用范围,标识一个类型的注射器只实例化一次,在同一个作用域内,只会生成一个实例,
然后在此作用域内共用一个实例。这样看起来很像单例模式,我们可以查看@Singleton其实就是@Scope的一个默认实现而已。当然,你得是同一个Component对象来生成
Dagger为我们提供了Scope的一种实现Singleton。单例???no!!!no!!!no!!!不是这么简单的。先看一下它的代码:
@Scope @Documented @Retention(RUNTIME) public @interface Singleton {}
在Dagger中我们可以自定义注解,譬如我们可以照着上面的模版自定义一个PreScope。
@Scope @Retention(RetentionPolicy.RUNTIME) public @interface PreScope { }
我们自定义的这个PreScope注解也有和Singleton同样的作用(单例)。下面看一下它的使用!!!
@Module public class AppModule7 { private App7 app; public AppModule7(App7 app) { this.app = app; } @Provides @Singleton public App7 provideApp() { return app; } @Provides @Singleton Context provideApplicationContext() { return app.getApplicationContext(); } } @Singleton @Component(modules = {AppModule7.class}) public interface AppComponent7 { void inject(App7 app); //因为AppComponent会被dependencies,所以此处Module中提供的内容,我们需要在此处声明一下 App7 getApp(); Context getApplicationContext(); }
@Module public class ActivityModule7 { @Provides @PreScope public DependencyPresenter7 getDependencyPresenter(App7 app){ return new DependencyPresenter7(app); } } @PreScope @Component(modules = ActivityModule7.class,dependencies = AppComponent7.class) public interface ActivityComponent7 { void inject(TargetActivity71 activity71); void inject(TargetActivity72 activity72); } public class App7 extends Application { private AppComponent7 mAppComponent7; private ActivityComponent7 mActivityComponent7; @Override public void onCreate() { super.onCreate(); mAppComponent7 = DaggerAppComponent7.builder().appModule7(new AppModule7(this)).build(); mAppComponent7.inject(this); mActivityComponent7 = DaggerActivityComponent7.builder().appComponent7(mAppComponent7).build(); } public AppComponent7 getAppComponent7(){ return mAppComponent7; } public ActivityComponent7 getActivityComponent7(){ return mActivityComponent7; } } public class DependencyPresenter7 { public DependencyPresenter7(App7 app){ Log.d("Dagger.class","DependencyPresenter7-----构造器被调用--------"); } public void printMethod(){ Log.d("Dagger.class","DependencyPresenter7-----printMethod()-----"); } } public abstract class BaseActivity712 extends Activity { private ActivityComponent7 mActivityComponent7; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); App7 app712 = (App7) getApplication(); mActivityComponent7 = app712.getActivityComponent7(); inject(mActivityComponent7); } public abstract void inject(ActivityComponent7 activityComponent7); } public class TargetActivity71 extends BaseActivity712 { @Inject DependencyPresenter7 mDependencyPresenter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Log.d("Dagger.class","TargetActivity71---mDependencyPresenter地址值-------"+mDependencyPresenter.toString()); } @Override public void inject(ActivityComponent7 activityComponent7) { activityComponent7.inject(this); } public void jump(View v){ startActivity(new Intent(this,TargetActivity72.class)); } } public class TargetActivity72 extends BaseActivity712 { @Inject DependencyPresenter7 mDependencyPresenter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Log.d("Dagger.class","TargetActivity72---mDependencyPresenter地址值-------"+mDependencyPresenter.toString()); } @Override public void inject(ActivityComponent7 activityComponent7) { activityComponent7.inject(this); } }
上面的代码我们使用了Dagger默认实现的@Singleton和自定义的@PreScope注解一起实现单例。我们之所以不只用dagger提供的Singleton而且还用自定义的,是因为我们使用的域不一样,当不同的Component有依赖依赖或包含关系的时候就不能用同样的Scope,就需要我们自定义。
下面是我在学习过程中总结的结论:
1 必须使用同一个Component对象来生成,也就是DaggerActivityComponent7.builder().build()只能执行一次。
2 Component和它的Module要使用相同的Scope。同一个Module中需要使用同样的Scope,否则相应的Component不知道使用什么Scope
3 有依赖关系或者包含关系的Component不能使用同样的Scope。
上面的三条结论就是在学习使用Singleton的时候总结出的,大家在学习的时候,最好自己也验证一下。