Dagger2快速上手系列二

学习札记:Dagger2快速上手系列一
学习札记:Dagger2快速上手系列二

上文我们简单的介绍了Dagger2的的快速使用,
这篇文章来说一说Dagger2的一些坑和注意事项。

1.@Named注解的使用
Dagger2中用@Name来依赖注入的对象做限定,这句话是什么意思呢,也就是说比如我们在上文的例子中,我们通过依赖注入返回SUserManager对象,如果此时我们需要返回两个不同这个对象,我们在SUserModule返回的只有一个,这个时候我们在依赖注入的地方和Module的工厂方法中加入同样的这个Name注解,就可以区分返回不同的对象了。Named这个注解本身是可以有参数,也可以通过自定义注解用Qualifier来注解这个自定义注解,因为Named这个注解就是用Qualifier这个注解的注解,下面通过代码看一看.

容器中的代码:

public class MainActivity extends AppCompatActivity {


    @Named("release")
    @Inject
    SUserManager daggerUserManager;
    @Named("debug")
    @Inject
    SUserManager daggerUserManagerDebug;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

       DaggerSUserComponent.create().inject(this);
  
        daggerUserManager.register();
    }
}

工厂中的代码


public class SUserModule{

  @Provides
    public SUserStore provideSuserStrore() {
        return new SUserStore ();
    }
    @Provides
    public SApiService provideApiService() {
        return new SApiService();
    }

    @Named("release")
    @Provides
    public SUserManager provideUserManager(SApiService apiService, SUserStore userStore) {

        return new SUserManager(apiService, userStore);

    }
   	@Named("debug")
    @Provides
    public SUserManager provideUserManagerForDebug(SApiService apiService, SUserStore userStore) {

        return new SUserManager(apiService, userStore);

    }
}

2.作用域的坑

举个简单的例子,比如我们在网络请求的时候,假设我们用到了一个OkHttpClient,我们在创建了一个新的Module,并提供了提供了一个实例,然后在需要注入的时候 用@Inject就可以使用了:

@Module
public class SUserModule{

	/*...
	省略其他代码
	...*/
    @Singleton
    @Provides
    public OkHttpClient provideOkHttoClinet(){

       return new OkHttpClient.Builder().build();
    }
}

这样咋一看没有什么问题,但是我们每次用到这个得时候,都会重新创建一遍OkHttpClient,这样就造成了性能的消耗,这个时候Dagger2为我们增加了一个 @Singleton来表明这个OkHttpClient是个单例,但是实际上,他只是做容器内的单例,也就是我们在MainActivity中使用OkHttpClient时,他是个单例,在另外的Activity中,比如登录的Acvitity,它又重新被创建了,那怎么办才能做到唯一呢,因为@Singleton是依附于Component的,一般的情况下,我们会写个App的Component,在Application的初始化中去注入进去。让其他的Component去依赖这个AppComponent,下面请看下代码,
我们在AppComponent中提供获取单例的OkHttpClient的声明。

@Singleton
@Component(modules = AppModule.class)
public interface AppComponent {
 OkHttpClient okHttoClinet();
}

我们在AppModule中实例化OkHttpClent,这个时候SUserModule里面的OkHttpClient就可以去掉了。

@Module
public class AppModule {
    @Singleton
    @Provides
    public OkHttpClient provideOkHttpClient(){
        return new OkHttpClient();
    }
}

我们在Application中初始化AppComponent


public class MyApplication exntends Application{

		private AppComponent appComponent;

		public AppComponent getAppComponent(){
			return appComponent;
		}
		 @Override
		protected onCreate(){
			super.onCreate();
			appComponent=DaggerAppComponent().create();
		}
}

我们让其他Component依赖于AppComponent,需要注意的是.由于AppComponent已经用了@Singleton这个注解来注解AppComponent了,所以在SUserComponent中需要用一个自定义scope来注解当前的Component,即有dependencies关系的组件之间的scope是不能相同的。

@ActivityScope
@Component(modules = {SUserModule.class,dependencies=AppComponent.class})
public interface SUserComponent {

    void inject(MainActivity activity);
}


自定义的scope


package com.android.seven.dagger2.dagger;

import java.lang.annotation.Documented;
import java.lang.annotation.Retention;

import javax.inject.Scope;
import javax.inject.Singleton;

import static java.lang.annotation.RetentionPolicy.RUNTIME;


@Scope
@Documented
@Retention(RUNTIME)
public @interface ActivityScope {
}

3,其他需要注意的地方
a.Component中需要inject的地方不能使用父类替换子类作为参数,这个是注解迷失的坑。举个例子比如在SUerComponent中的inject(MainActivity activity);这个方法中MainActivity不能用器父类替换,只能是MainActivity;
b.Component关联的modules中不能有重复的provides,也就是关联的多个module不能提供相同的对象;
b.module中provide,如果使用了scope,则component必须与其一致,比如AppComponent,如果module中provide没有使用scope,则component无所谓,如果说component有dependencies关系,scope必须不一样,即有依赖关系的component不一样;
c.Sigleton的component不能依赖其他组件;
d.没有scope的component不能依赖有scope的component;
e.一个component不能有多个scope(subComponent除外)
f.sigleton的生命周期依附于component。

暂时只整理这么多,本文如果有不正之处,烦请之处,感谢感谢!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值