学习札记:Dagger2快速上手系列一
学习札记:Dagger2快速上手系列二
一.什么是Dagger2
Dagger2是Dagger的升级版,是一个依赖注入框架,第一代由大名鼎鼎的Square公司共享出来,第二代则是由谷歌接手后推出的,现在由Google接手维护,传送门Dagger2的GitHub地址
二.为什么使用Dagger2
上面我们说到,Dagger2是一个依赖注入框架,那什么是依赖注入呢,可以抽象的理解为其实就是将一个类里面包含另外一个类实例的引用。
我们常用的在属性,方法中参数 ,甚至通过接口中抽象方法中的参数等方式都可以实现依赖注入,那为什么还要使用Dagger2呢,当然如果是单兵作战,项目不大的话,不用也没关系,但是在项目很大,协同工作中,建议还是使用Dagger2,因为你会发现它会让你的项目结构清晰,维护起来也更加方便,降低代码耦合度,另外它是编译时生成一些代码,也不会产生性能影响。
三.如何使用Dagger2
1.配置:在项目app目录下build.gradle的dependencies中加入这两行
annotationProcessor ‘com.google.dagger:dagger-compiler:2.24’
implementation ‘com.google.dagger:dagger :2:2.24’
2.配置完以后,我们通过一个简单的例子来走一遍,看一下Dagger2到底哪里好用了。
这个说一个简单的场景,比如我们在做注册的时候,需要本地和服务器存一些数据,我们会有一个管理类,
分别持有本地和服务器操作的类的实例。
/**
管理类
**/
public class SUserManager {
SApiService apiService;
SUserStore userStore;
public SUserManager( SApiService apiService, SUserStore userStore) {
this.apiService =apiService;
this.userStore =userStore;
}
public void register() {
apiService.register();
userStore.register();
}
}
/**
服务器操作
**/
public class SApiService {
public SApiService() {
Log.d(TAG, "SApiService: ");
}
public void register(){
Log.d(TAG, "register: >>>>>>>");
}
}
/**
本地操作
**/
public class SUserStore {
public SUserStore() {
Log.d(TAG, "SUserStore: ");
}
public void register() {
Log.d(TAG, "register: >>>>>>>>");
}
}
一般情况下我们都会这么去写,然后在需要引用UserManager地方实例化一个对象,然后进行操作,这样当然也没什么问题,但是如果说我们做一下简单的调整,比如说我在注册的时候需要修改一下本地注册时的参数,就比如说一个上下文对象吧,这个时候是不是要修改UserManger,在调用UserManager实例中的也会去修改。项目小还稍微好点,要是项目大,需要改的东西可能就很多了,甚至会出错,所以Dagger2就是为了处理这些问题。
那么该如果使用Dagger2来解耦呢,让项目结构更清晰呢。首先我们来看张图
其实就是我们通过被component注解的接口将被Module注解工厂中的生成的对象注入到Activity等容器中。我们通过代码理解下这句话。
首先我们要搞个纽带,也就是被component注解的接口。
@Component(modules = {SUserModule.class})
public interface SUserComponent {
void inject(MainActivity activity);
}
我们在这里支持持有了Activity中引用,并且在Component引入了SUserModule这个“对象工厂”
@Module
public class SUserModule{
@Provides
public SUserStore provideSuserStrore() {
return new SUserStore ();
}
@Provides
public SApiService provideApiService() {
return new SApiService();
}
@Provides
public SUserManager provideUserManager(SApiService apiService, SUserStore userStore) {
return new SUserManager(apiService, userStore);
}
}
我们在MainActivity中使用Inject注解需要注入的对象实例,然后编译通过后,使用SUserComponent.create().inject(this),注入就可以使用了。
public class MainActivity extends AppCompatActivity {
@Inject
SUserManager daggerUserManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DaggerSUserComponent.create().inject(this);
daggerUserManager.register();
}
}
这样咋一看,是变得复杂了,代码越写看起来越多,但是实际上当你SUserManager 被多个地方引用时,你基本上只需要改一下SUserModule这个里面的代码,这样是不是让你的代码维护起来更加的方便,结构看起来也更加清晰。
好了,简单的使用就说完了,我们来做个简单的总结。上面我们主要用到了四个注解,@Module @Provides
@Component @Inject,下面梳理下这几个注解使用:
@Module:用来注解生成对象的工厂,让Dagger2知道从哪里去找对象;
@Provides:用在module工厂中方法的注解,告诉Dagger2我们想要构造对象并提供这些依赖;
@Component:如上图中描述,是一个纽带;
@Inject:通常在需要依赖的地方注解。
暂时只整理这么多,本文如果有不正之处,烦请之处,感谢感谢!