Dagger2 2.14.1中SettingsFragment无法继承DaggerFragment获取依赖问题
最近在学习Dagger 2(版本2.14.1),碰到个头疼的问题:我的SettingsFragment需要继承PreferenceFragmentCompat来实现偏好设置页面,但Java不支持多继承,没办法同时继承DaggerFragment来自动实现依赖注入。
我已经给SettingsFragment建了对应的空模块(SettingsModule)和子组件(SettingsSubcomponent),目的就是能拿到应用层级创建的依赖。补充下:我的ApplicationComponent已经包含了UIBuildersModule,下面是相关的build.gradle代码片段:
implementation 'com.google.dagger:dagger:2.14.1' annotationProcessor 'com.google.dagger:dagger-compiler:2.14.1' implementation 'com.google.dagger:dagger-android:2.14.1' annotationProcessor 'com.google.dagger:dagger-android-processor:2.14.1' implementation 'androidx.preference:preference:1.1.1'
啊,原来如此!不用死磕继承DaggerFragment,咱们可以通过手动触发依赖注入的方式搞定,具体步骤如下:
让
SettingsFragment实现HasFragmentInjector接口
这一步是让Dagger能识别并处理这个Fragment的注入,同时在onCreate里手动调用注入方法:public class SettingsFragment extends PreferenceFragmentCompat implements HasFragmentInjector { @Inject DispatchingAndroidInjector<Fragment> fragmentInjector; @Override public void onCreate(Bundle savedInstanceState) { AndroidInjection.inject(this); // 关键:手动触发注入 super.onCreate(savedInstanceState); // 现在就能正常用@Inject标记的依赖啦 } @Override public AndroidInjector<Fragment> fragmentInjector() { return fragmentInjector; } @Override public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { setPreferencesFromResource(R.xml.settings_preferences, rootKey); } }完善子组件与模块的关联
虽然你的SettingsModule和SettingsSubcomponent是空的,但得确保它们和ApplicationComponent正确绑定:- 子组件要继承
AndroidInjector<SettingsFragment>,并定义对应的Builder:@Subcomponent public interface SettingsSubcomponent extends AndroidInjector<SettingsFragment> { @Subcomponent.Builder abstract class Builder extends AndroidInjector.Builder<SettingsFragment> {} } - 在
UIBuildersModule中添加这个子组件的绑定,让Application级别的组件知道它的存在:@Module(subcomponents = SettingsSubcomponent.class) public abstract class UIBuildersModule { @Binds @IntoMap @FragmentKey(SettingsFragment.class) abstract AndroidInjector.Factory<? extends Fragment> bindSettingsFragmentInjectorFactory(SettingsSubcomponent.Builder builder); }
- 子组件要继承
确认Application的Dagger配置
确保你的自定义Application实现了HasAndroidInjector,并且注入了对应的Dispatcher:public class MyApp extends Application implements HasAndroidInjector { @Inject DispatchingAndroidInjector<Object> androidInjector; @Override public void onCreate() { super.onCreate(); DaggerApplicationComponent.create().inject(this); } @Override public AndroidInjector<Object> androidInjector() { return androidInjector; } }
这么操作之后,SettingsFragment既能正常继承PreferenceFragmentCompat做设置页面,又能通过Dagger拿到应用层级的依赖,完美解决多继承的限制!
内容的提问来源于stack exchange,提问作者Eric

