我研究了一些有关新的dagger.android方法的教程,但是做得不好。我使用子组件生成器构建了一个简单的教程,但无法将其转换为新方法。所有教程和文章都将必需的部分留空。
此示例出于学习目的,可能不适合实际情况,我仅打算实现字段注入,而构造函数注入可能更合适。
范围
@Scope
@Retention(RetentionPolicy.RUNTIME)
public @interface ActivityScope {
}
父组件
@Component(modules = ApplicationModule.class)
@Singleton
public interface ApplicationComponent {
// Calls SubComponent Builder from MainActivity using ApplicationComponent
ToastMakerSubComponent.Builder toastMakerBuilder();
}
父模块,我没有在应用模块中使用@BindsInstance来学习不同的方法
@Module(subcomponents = {ToastMakerSubComponent.class})
public class ApplicationModule {
private Context context;
public ApplicationModule(Context context) {
this.context = context;
}
@Provides
@Singleton
SharedPreferences provideSharedPreferences() {
System.out.println("ApplicationModule context: " + context);
return context.getSharedPreferences("PrefName", Context.MODE_PRIVATE);
}
}
子组件
@ActivityScope
@Subcomponent(modules = {ToastMakerModule.class})
public interface ToastMakerSubComponent {
void inject(MainActivity mainActivity);
/*
Builder is called from Parent Component,
and parent component is called from scope(Activity, Fragment, etc.)
*/
@Subcomponent.Builder
interface Builder {
ToastMakerSubComponent build();
@BindsInstance
Builder context(Context context);
}
}
子组件模块
@Module
public class ToastMakerModule {
@ActivityScope
@Provides
ToastMaker provideToastMaker(Context context) {
System.out.println("ToastMakerModule context: " + context);
return new ToastMaker(context);
}
}
实例化MyApplication内部的ApplicationComponent
mApplicationComponent = DaggerApplicationComponent
.builder()
.applicationModule(new ApplicationModule(getApplicationContext()))
.build();
并在Activity中获取子组件
ApplicationComponent applicationComponent = ((MyApplication) getApplication()).getApplicationComponent();
ToastMakerSubComponent toastMakerSubComponent = applicationComponent
.toastMakerBuilder()
.context(this)
.build();
toastMakerSubComponent.inject(this);
在遵循this,this和this教程之后,我将以下内容构建为
@Component(modules = ApplicationModule.class)
@Singleton
public interface ApplicationComponent {
// What should i put here ???
}
父模块,但我不知道如何提供provideSharedPreferences
@Module(subcomponents = {ToastMakerSubComponent.class})
abstract class ApplicationModule {
@Binds
@IntoMap
@ActivityKey(MainActivity.class)
abstract AndroidInjector.Factory<? extends MainActivity>
bindYourActivityInjectorFactory(ToastMakerSubComponent.Builder builder);
}
缺少子组件ToastMakerSubComponent build();
和@BindsInstance Builder context(Context context);
,我应该如何将它们添加到此组件中。
@ActivityScope
@Subcomponent(modules = {ToastMakerModule.class})
public interface ToastMakerSubComponent extends AndroidInjector<MainActivity> {
// ??? Is this required?
void inject(MainActivity mainActivity);
@Subcomponent.Builder
abstract class Builder extends AndroidInjector.Builder<MainActivity> {
???
}
}
我还看到@ContributesAndroidInjector
,在此示例中它适合哪里?
答案 0 :(得分:2)
以下是变化的地方:https://www.diffchecker.com/3IL8UQ7P
使应用程序组件扩展AndroidInjector<MyApplication>
并包括AndroidSupportInjectionModule
@Component(modules = {ApplicationModule.class, AndroidSupportInjectionModule.class})
@Singleton
public interface ApplicationComponent extends AndroidInjector<MyApplication> {
}
使子组件扩展AndroidInjector<MainActivity>
和构建器AndroidInjector.Builder<MainActivity>
,并使用seedInstance
为@BindsInstance
方法提供参数。
@ActivityScope
@Subcomponent(modules = {ToastMakerModule.class})
public interface ToastMakerSubComponent extends AndroidInjector<MainActivity> {
@Subcomponent.Builder
abstract class Builder extends AndroidInjector.Builder<MainActivity> {
@Override
public void seedInstance(MainActivity instance) {
context(instance);
}
@BindsInstance
public abstract Builder context(Context context);
}
}
将子组件构建器的绑定添加到应用程序组件中安装的模块:
@Module(subcomponents = {ToastMakerSubComponent.class})
public abstract class ApplicationModule {
private Context context;
public ApplicationModule(Context context) {
this.context = context;
}
@Provides
@Singleton
SharedPreferences provideSharedPreferences() {
System.out.println("ApplicationModule context: " + context);
return context.getSharedPreferences("PrefName", Context.MODE_PRIVATE);
}
@Binds
@IntoMap
@ActivityKey(MainActivity.class)
abstract AndroidInjector.Factory<? extends Activity> bindMainActivityFactory(ToastMakerSubComponent.Builder builder);
}
让框架类扩展Dagger*
对应类,或者在不能使用继承的情况下实现Has*Injector
接口
public class MyApplication extends DaggerApplication {
@Override
protected AndroidInjector<? extends DaggerApplication> applicationInjector() {
return DaggerApplicationComponent.create();
}
}
public class MainActivity extends DaggerAppCompatActivity {
@Inject
SharedPreferences sharedPreferences;
@Inject
ToastMaker toastMaker;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toastMaker.showToast("sharedPreferences " + sharedPreferences);
}
}