有关Dagger的Scope

来源:互联网 发布:钻石展位 淘宝首页 编辑:程序博客网 时间:2024/06/05 09:33

1、假如Module中没有使用Scope,如@Singleton,则Component的定义的时候可以没有Scope

@Component(modules = {AppModule.class})public interface AppComponent {    Application getApplication();}

@Modulepublic 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();}
@Modulepublic 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

@Modulepublic 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);}

@Modulepublic class CommonModule {    @Provides    @MyScope    User2 provideUser2() {        return new User2();    }}
@Modulepublic 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是单实例的







0 0
原创粉丝点击