ベースモジュールにBaseUiFragmentがあり、UiComponentを注入する必要があります。アプリケーションモジュールでAndroidInjectionをベースクラスで使用するには?
public abstract class BaseUiFragment extends Fragment {
@Inject
UiComponent mUiComponent;
@Override
public final void onAttach(Context context) {
AndroidSupportInjection.inject(this); //this is subclass
super.onAttach(context);
}
}
@Subcomponent
public interface BaseUiFragmentSubcomponent extends AndroidInjector<BaseUiFragment> {
@Subcomponent.Builder
abstract class Builder extends AndroidInjector.Builder<BaseUiFragment> {
}
}
@Module(subcomponents = BaseUiFragmentSubcomponent.class)
public abstract class BaseUiFragmentModule {
@Binds
@IntoMap
@FragmentKey(BaseUiFragment.class) // key in MapProviderFactory
abstract AndroidInjector.Factory<? extends Fragment>
bindBaseUiFragmentInjectorFactory(BaseUiFragmentSubcomponent.Builder builder);
private BaseUiFragmentModule() {}
}
、UiComponentModuleがUIComponentを提供し、MainFragmentはBaseUiFragmentを拡張します。
@Module
public class UiComponentModule {
@Provides
static UiComponent provideUiComponent() {
return new UiComponent() {};
}
}
@Singleton
@Component(modules = {AndroidSupportInjectionModule.class, BaseUiFragmentModule.class, UiComponentModule.class})
public interface ApplicationComponent extends AndroidInjector<MainApplication> {
@Component.Builder
abstract class Builder extends AndroidInjector.Builder<MainApplication> {
}
}
public class MainFragment extends BaseUiFragment {
@Override
public View onCreateViewImpl(Bundle savedInstanceState) {
return new View(getContext());
}
}
場合AndroidSupportInjection.inject(本)それは動作しません。 DispatchingAndroidInjectorのmaybeInject()がfalseを返すため、
injectorFactoriesには(MainFragment.class、...)はありませんが、AndroidSupportInjection.inject(this)はありません。これはMainFragmentです。
public boolean maybeInject(T instance) {
Provider<AndroidInjector.Factory<? extends T>> factoryProvider =
injectorFactories.get(instance.getClass());
if (factoryProvider == null) { // factoryProvider is null
return false;
}
// ...
}
したがって、AndroidInjection(AndroidSupportInjection)をベースクラスで使用するにはどうすればよいですか?
Googleのインジェクトのimpl:分析の数日後
それはのみinstance.getClass(だ)
public boolean maybeInject(T instance) {
Provider<AndroidInjector.Factory<? extends T>> factoryProvider =
injectorFactories.get(instance.getClass());
if (factoryProvider == null) {
return false;
}
// ...
}
私のimpl:トラバーサルそれとそのスーパークラス、問題が解決され、それは、factoryProviderを取得するリフレクションを使用します。
public boolean maybeInject(T instance) {
Provider<AndroidInjector.Factory<? extends Fragment>> factoryProvider
= injectorFactories.get(fragment.getClass());
Class fragmentSuperclass = fragment.getClass().getSuperclass();
while (factoryProvider == null && fragmentSuperclass != Fragment.class) {
factoryProvider = injectorFactories.get(fragmentSuperclass);
fragmentSuperclass = fragmentSuperclass.getSuperclass();
}
if (factoryProvider == null) {
return false;
}
// ...
}
だから、それはこれだけの方法であるか、そしてGoogleは、実装を変更することができますか?
をしたいかである「あなたの継承階層の各リーフのためのサブコンポーネントを作成する」と思い、良い方法ではありません。私のベースライブラリを使用している呼び出し元には親切ではありません。 –
@ApolunorJing Daggerは_コンパイル時コード生成ソリューションです。 'FooFragment'がフィールド' @Inject Bar bar'を持っていると、Daggerはコンパイル時にそれを検査せずに(つまり、そのためのセッターを書くことはできません)、そのようにする方法はまったくありませんTrevはここにそれを持っています。答えに+1。 –