初入门dagger2,写小demo来学习
参考Dagger2的入坑指南[捂脸][详]!!
首先添加依赖
implementation 'com.google.dagger:dagger:2.21'
annotationProcessor 'com.google.dagger:dagger-compiler:2.21'
implementation 'com.google.dagger:dagger-android:2.21'
implementation 'com.google.dagger:dagger-android-support:2.21' //用于提供support类相关功能
annotationProcessor 'com.google.dagger:dagger-android-processor:2.21'
第一个需求:在activity实例化UserService业务类
通常做法:在activity 直接new一个UserService。
dagger2做法:做最简单的注入。需要 @inject 与 @Component配合注解构成
业务类代码:
public class UserService {
@Inject//构造方法,用于告诉Dagger,生成对象时可以使用这个构造方法。这就是注射液
public UserService() {
}
//假设请求网络数据方法
public String request(){
return "request";
}
}
还需要一个注射器Component,和activity产生产生关系
@Component
public interface MainComponent {
//说明要在哪个activity注入
void inject(MainActivity mainActivity);
}
写完后rebuild一下生成一个DaggerMainComponent,提供注入,名字生成的规则是DaggerXXComponent
然后,在调用方MainActivity里就可以通过@inject来获取到需要的UserService 对象:
public class MainActivity extends AppCompatActivity {
@Inject//要new哪个,就inject哪个。
UserService service;
TextView tv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DaggerMainComponent.builder().build().inject(this);//声明注入到这个activity,绑定注入对象的关系
tv=(TextView)findViewById(R.id.tv);
tv.setText(service.request());
}
}
需求改变:Userservic 需要一个Gson对象。
因为第三方的代码文件你是改不了的,没法在里面写注解,所以要换一种方式提供注射液
public class UserService {
Gson gson;
@Inject//构造方法,用于提供对象
public UserService(Gson gson) {
this.gson=gson;
}
public Gson getGson() {
return gson;
}
//假设请求网络数据方法
public String request(){
return "request";
}
}
如果要实例化Gson,按照上面的步骤来说,应该在Gson的构造函数标识@inject。才可以被实例化,由于无法做到,所以就只能声明Module注射液仓库来提供Gson对象。
@Module
public class UserModule {
@Provides//告诉Dagger我们想要构造对象并提供这些依赖
Gson provideGson() {
return new Gson();
}
// 在不是第三方的代码里,如果有了module,可以把构造函数的@inject去掉,依赖对象由module提供。
// 如果没有去掉UserService的inject并且也在module提供了实例,也是ok的,只是UserService构造函数的@inject是无效的。
//记住,@Module级别高于@Inject。
/* @Provides
UserService providesUserService(Gson gson) {
return new UserService(gson);
}
*/
}
修改Component,构建module的关系
@Component(modules = UserModule.class)//可以有多个modules={xxxModule.class,XXclass,等等}
public interface MainComponent {
//说明要在哪个activity注入
void inject(MainActivity mainActivity);
}
重新编译,在activity调用
public class MainActivity extends AppCompatActivity {
@Inject//要new哪个,就inject哪个。
UserService service;
TextView tv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DaggerMainComponent.builder().userModule(new UserModule()).build().inject(this);//在activity里初始化
tv=(TextView)findViewById(R.id.tv);
tv.setText(service.getGson().getClass().getName());
}
}
如果Service需要的对象Context,module要怎么提供?
public class UserService {
Gson gson;
Context context;
@Inject//构造方法,用于提供对象
public UserService(Gson gson, Context context) {
this.gson=gson;
this.context=context;
}
public Gson getGson() {
return gson;
}
public Context getContext(){
return context;
}
//假设请求网络数据方法
public String request(){
return "request";
}
}
Module可以通过构造函数去提供实例,并提供出去。
@Module
public class UserModule {
Context mContext;
// Module可以通过构造函数去提供实例(因为这个构造函数会在activity初始化呀),并提供出去
public UserModule(Context context) {
this.mContext=context;
}
@Provides//提供gson
Gson provideGson() {
return new Gson();
}
@Provides//提供context
Context provideContext(){
return mContext;
}
}
然后编译,在activity调用
public class MainActivity extends AppCompatActivity {
@Inject//要new哪个,就inject哪个。
UserService service;
TextView tv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Module构造函数会在activity初始化
DaggerMainComponent.builder().userModule(new UserModule(this)).
build().inject(this);
tv=(TextView)findViewById(R.id.tv);
tv.setText(service.getContext().toString());
}
}
到这里,就算基本入门啦,接下来,就要到学习笔记2看慢慢深入啦