传说中的android三件套,Rxjava,Dagger,MVP火的不能再火了,今天我们通过代码看看Dagger2是怎么实现的。
Dagger2中比较重要的注解:
@Module用来标注Module类,Module直接粗暴地说就是一个存放我们需要实例的容器,我们需要的实例都通过Module来获取
@Component连接桥梁,注入器,Dagger2最重要的一个作用就是解耦,所以我们需要一个桥梁来把提供实例和需要实例的对象联系起来。
@Inject标注我们那些实例需要注入,或者那个构造为我们提供实例
看代码MainActivity:
public class MainActivity extends AppCompatActivity {
@Inject
UserInfo userInfo;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//桥梁
MainComponent mainComponent = DaggerMainComponent.builder().mainModle(new MainModle()).build();
//注入操作
mainComponent.inject(this);
Log.e("Main", userInfo.hashCode() + "");
}
}
MainActivity很简单, @Inject标注需要注入的对象。
MainComponent代码:
@Component(modules =MainModle.class )//桥梁,建立联系
public interface MainComponent {
void inject(MainActivity mainActivity);
}
MainModle代码:
@Module
public class MainModle {
@Provides//提供实例
UserInfo provideUserInfo(){
return new UserInfo();
}
}
代码很简单,Dagger最简单最标准的用法。我们主要来分析一下他是怎么实现注入的。
MainComponent是一个接口,我们首先看看他的实现类DaggerMainComponent(rebuild自动生成
),我们可以看出来DaggerMainComponent是根据Builder模式创建出来的,看下代码:
@Generated("dagger.internal.codegen.ComponentProcessor")
//Provider是一个接口,只有一个get方法,get方法返回的类型就是我们传进去的泛型
private Provider<UserInfo> provideUserInfoProvider;
//MembersInjector也是一个接口,一个方法injectMembers
private MembersInjector<MainActivity> mainActivityMembersInjector;
private DaggerMainComponent(Builder builder) {
//处理builder对象
initialize(builder);
}
//builder方法,返回一个Builder对象
public static Builder builder() {
return new Builder();
}
public static MainComponent create() {
return builder().build();
}
private void initialize(final Builder builder) {
this.provideUserInfoProvider = MainModle_ProvideUserInfoFactory.create(builder.mainModle);
//MembersInjectors.noOp()好像没什么大的用处,这里就不做解释了
//如果有大神知道请指教,不胜感激
this.mainActivityMembersInjector = MainActivity_MembersInjector.create((MembersInjector) MembersInjectors.noOp(), provideUserInfoProvider);
}
@Override
public void inject(MainActivity mainActivity) {
mainActivityMembersInjector.injectMembers(mainActivity);
}
public static final class Builder {
private MainModle mainModle;
private Builder() {
}
//调用build方法,创建桥梁
public MainComponent build() {
if (mainModle == null) {
this.mainModle = new MainModle();
}
return new DaggerMainComponent(this);
}
public Builder mainModle(MainModle mainModle) {
if (mainModle == null) {
throw new NullPointerException("mainModle");
}
//给mainModle 赋值
this.mainModle = mainModle;
return this;
}
}
}
上面写注释了,然后我们着重看initialize和inject两个方法,首先我们看看initialize方法,我们看看是怎么给provideUserInfoProvider 赋值的,通过该对象的get方法我们就可以得到UserInfo实例了。
/**
*Factory是一个Provider的子类接口
*/
@Generated("dagger.internal.codegen.ComponentProcessor")
public final class MainModle_ProvideUserInfoFactory implements Factory<UserInfo> {
private final MainModle module;
public MainModle_ProvideUserInfoFactory(MainModle module) {
assert module != null;
this.module = module;
}
//实现get方法,我们可以看到在这里调用了我们MainModle 的provideUserInfo方法
//在这里我们也可以看到如果我们在provideUserInfo方法中返回null会直接抛出异常。
@Override
public UserInfo get() {
UserInfo provided = module.provideUserInfo();
if (provided == null) {
throw new NullPointerException("Cannot return null from a non-@Nullable @Provides method");
}
return provided;
}
//外面调用的create方法
public static Factory<UserInfo> create(MainModle module) {
return new MainModle_ProvideUserInfoFactory(module);
}
}
我们可以看出来,这个get方法中返回的对象,就是我们在MainModle中返回的对象。很简单的一个类,就一个方法,没什么可说的。我们继续看是怎么给mainActivityMembersInjector赋值的。
@Generated("dagger.internal.codegen.ComponentProcessor")
public final class MainActivity_MembersInjector implements MembersInjector<MainActivity> {
private final MembersInjector<AppCompatActivity> supertypeInjector;
private final Provider<UserInfo> userInfoProvider;
public MainActivity_MembersInjector(MembersInjector<AppCompatActivity> supertypeInjector, Provider<UserInfo> userInfoProvider) {
//赋值
assert supertypeInjector != null;
this.supertypeInjector = supertypeInjector;
assert userInfoProvider != null;
this.userInfoProvider = userInfoProvider;
}
//这个方法使我们重点关注的
@Override
public void injectMembers(MainActivity instance) {
//非空判断
if (instance == null) {
throw new NullPointerException("Cannot inject members into a null reference");
}
supertypeInjector.injectMembers(instance);
//真正的赋值操作,所有的一切都为了这一步
//MainActivity中我们用@inject标注的成员变量userInfo
//用userInfoProvider的get方法获取UserInfo对象赋值给他
//实际上就是MainModle中provideUserInfo方法的返回值
instance.userInfo = userInfoProvider.get();
}
public static MembersInjector<MainActivity> create(MembersInjector<AppCompatActivity> supertypeInjector, Provider<UserInfo> userInfoProvider) {
return new MainActivity_MembersInjector(supertypeInjector, userInfoProvider);
}
}
接着我们看inject方法,在inject方法中,我们调用了mainActivityMembersInjector的injectMembers方法,也就是我们刚刚看的真是赋值的操作。到这里就完成了所有的赋值操作。
Dagger原理很简单,在Module中有多少个@Provider标注的方法,就会生成多少个Provider类,在这些类中重写get方法,根据返回值类型调用Module不同的方法。然后把这些Provider对象传递传递给注入器对象,再注入器对象中,我们找到页面上所有需要注入赋值的对象,也就是用@inject标注的对象,用不同的Provider的get方法给这些需要注入的对象赋值。
新司机上路请大家多多指教。
大家可以关注一下,一起学习一起进步。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。