Are you still using interface decoupling? Why don’t you start using it when it looks cleaner? The purpose used in our project: To decouple objects, avoiding a large number of interfaces passing parameters.
With that in mind, let us see what he has done for us.
Use the operation triad 1.@Inject
public class PhotoNewsFragment extends BaseFragment<IBasePresenter> implements ILoadDataView<List<PhotoInfo>> { // // @inject //protected T mPresenter; @Inject BaseQuickAdapter mAdapter; @ Override protected void initInjector () {DaggerPhotoNewsComponent. Builder () / / to rely on global There may be to use the global variables .applicationComponent(getAppComponent()) .photoNewsModule(new PhotoNewsModule(this)) .build() .inject(this); }}Copy the code
2.@module
@Module public class PhotoNewsModule { private final PhotoNewsFragment mView; public PhotoNewsModule(PhotoNewsFragment view) { this.mView = view; } @PerFragment @Provides public BaseQuickAdapter provideAdapter() { return new PhotoListAdapter(mView.getContext()); }}Copy the code
3.@Component
@PerFragment
@Component(modules = PhotoNewsModule.class)
public interface PhotoNewsComponent {
void inject(PhotoNewsFragment fragment);
}Copy the code
Click Make Project to use the Adapter in the first class.
It’s easy to use, so let’s see why we can use it and what the Dagger2 does for us in private. We’ll see some of the column methods it generates here
app/build/generated/source/apt/debug/....Copy the code
Two, corresponding generation
1. @ the module
public final class PhotoNewsModule_ProvideAdapterFactory implements Factory<BaseQuickAdapter> {
private final PhotoNewsModule module;
public PhotoNewsModule_ProvideAdapterFactory(PhotoNewsModule module) {
assert module != null;
this.module = module;
}
@Override
public BaseQuickAdapter get() {
return Preconditions.checkNotNull(
module.provideAdapter(), "Cannot return null from a non-@Nullable @Provides method");
}
public static Factory<BaseQuickAdapter> create(PhotoNewsModule module) {
return new PhotoNewsModule_ProvideAdapterFactory(module);
}
}
Copy the code
2,@Component
public final class DaggerPhotoNewsComponent implements PhotoNewsComponent {
private Provider<IBasePresenter> providePresenterProvider;
private Provider<BaseQuickAdapter> provideAdapterProvider;
private MembersInjector<PhotoNewsFragment> photoNewsFragmentMembersInjector;
private DaggerPhotoNewsComponent(Builder builder) {
assert builder != null;
initialize(builder);
}
public static Builder builder() {
return new Builder();
}
@SuppressWarnings("unchecked")
private void initialize(final Builder builder) {
this.providePresenterProvider =
DoubleCheck.provider(
PhotoNewsModule_ProvidePresenterFactory.create(builder.photoNewsModule));
this.provideAdapterProvider =
DoubleCheck.provider(PhotoNewsModule_ProvideAdapterFactory.create(builder.photoNewsModule));
this.photoNewsFragmentMembersInjector =
PhotoNewsFragment_MembersInjector.create(providePresenterProvider, provideAdapterProvider);
}
@Override
public void inject(PhotoNewsFragment fragment) {
photoNewsFragmentMembersInjector.injectMembers(fragment);
}
public static final class Builder {
private PhotoNewsModule photoNewsModule;
private ApplicationComponent applicationComponent;
private Builder() {}
public PhotoNewsComponent build() {
if (photoNewsModule == null) {
throw new IllegalStateException(PhotoNewsModule.class.getCanonicalName() + " must be set");
}
if (applicationComponent == null) {
throw new IllegalStateException(
ApplicationComponent.class.getCanonicalName() + " must be set");
}
return new DaggerPhotoNewsComponent(this);
}
public Builder photoNewsModule(PhotoNewsModule photoNewsModule) {
this.photoNewsModule = Preconditions.checkNotNull(photoNewsModule);
return this;
}
public Builder applicationComponent(ApplicationComponent applicationComponent) {
this.applicationComponent = Preconditions.checkNotNull(applicationComponent);
return this;
}
}
}
Copy the code
3, the annotation class generated by the current Fragment
public final class PhotoNewsFragment_MembersInjector implements MembersInjector<PhotoNewsFragment> { private final Provider<IBasePresenter> mPresenterProvider; private final Provider<BaseQuickAdapter> mAdapterProvider; public PhotoNewsFragment_MembersInjector( Provider<IBasePresenter> mPresenterProvider, Provider<BaseQuickAdapter> mAdapterProvider) { assert mPresenterProvider ! = null; this.mPresenterProvider = mPresenterProvider; assert mAdapterProvider ! = null; this.mAdapterProvider = mAdapterProvider; } public static MembersInjector<PhotoNewsFragment> create( Provider<IBasePresenter> mPresenterProvider, Provider<BaseQuickAdapter> mAdapterProvider) { return new PhotoNewsFragment_MembersInjector(mPresenterProvider, mAdapterProvider); } @Override public void injectMembers(PhotoNewsFragment instance) { if (instance == null) { throw new NullPointerException("Cannot inject members into a null reference"); } com.dl7.mvp.module.base.BaseFragment_MembersInjector.injectMPresenter( instance, mPresenterProvider); // assign..... here instance.mAdapter = mAdapterProvider.get(); } public static void injectMAdapter( PhotoNewsFragment instance, Provider<BaseQuickAdapter> mAdapterProvider) { instance.mAdapter = mAdapterProvider.get(); }}Copy the code
4. Annotation classes generated by BaseFragment
public final class BaseFragment_MembersInjector<T extends IBasePresenter> implements MembersInjector<BaseFragment<T>> { private final Provider<T> mPresenterProvider; public BaseFragment_MembersInjector(Provider<T> mPresenterProvider) { assert mPresenterProvider ! = null; this.mPresenterProvider = mPresenterProvider; } public static <T extends IBasePresenter> MembersInjector<BaseFragment<T>> create( Provider<T> mPresenterProvider) { return new BaseFragment_MembersInjector<T>(mPresenterProvider); } @Override public void injectMembers(BaseFragment<T> instance) { if (instance == null) { throw new NullPointerException("Cannot inject members into a null reference"); } instance.mPresenter = mPresenterProvider.get(); } public static <T extends IBasePresenter> void injectMPresenter( BaseFragment<T> instance, Provider<T> mPresenterProvider) {// assign the value.... here instance.mPresenter = mPresenterProvider.get(); }}Copy the code
Just a couple of annotations, Dagger generates a lot of code for us. Start following the process and looking at the code.
DaggerPhotoNewsComponent. Builder () / / here because I'm going to use the Application. Some of the members of the singleton variable applicationComponent (getAppComponent ()) .photoNewsModule(new PhotoNewsModule(this)) .build() .inject(this);Copy the code
The @Inject in the BaseFragment class is not specified here. It is more complex than the Inject in the current class. It also uses the Module Provides in the Application.
We see DaggerPhotoNewsComponent. Builder ().
— > Get a static class Builder
.photoNewsModule(new PhotoNewsModule(this))
— > Static class Builder with PhotoNewsModule (we wrote the PhotoNewsModule ourselves, calling the construct and passing in the current This (as a View))
.build()
— > Executes new DaggerPhotoNewsComponent(this) and calls initialize(Builder). In this initialization method, Will the annotation class executed dojo.provide PhotoNewsModule_ProvideAdapterFactory. Create (builder. PhotoNewsModule) method. (the inside of the incoming photoNewsModule) will perform the fragments generated annotation class PhotoNewsFragment_MembersInjector. Create (providePresenterProvider, provideAdapterProvider)
.inject(this);
photoNewsFragmentMembersInjector.injectMembers(fragment); At This point, we know that This is the current view, which assigns a value to the member variable mAdapter. This value is the generated Module generated annotation class, which holds the Module we wrote, which provides the construction of the Adapter.
@Override
public void injectMembers(PhotoNewsFragment instance) {
if (instance == null) {
throw new NullPointerException("Cannot inject members into a null reference");
}
com.dl7.mvp.module.base.BaseFragment_MembersInjector.injectMPresenter(
instance, mPresenterProvider);
instance.mAdapter = mAdapterProvider.get();
}Copy the code
The Dagger is simply constructed for decoupling to make the code look more elegant. When used in other ways, @Inject holds the View application and can be called back