gpt4 book ai didi

带有 BaseActivity 的 Android Dagger 2 可以减少样板文件

转载 作者:太空狗 更新时间:2023-10-29 16:29:19 24 4
gpt4 key购买 nike

当我想将每个 Activity 中的一些 Dagger 2 样板代码移动到 BaseActivity 时遇到了一些麻烦。

BaseActivity extends AppCompatActivity

我有多项 Activity ,例如:

ActivityA extends BaseActivity implements InterfaceA;
ActivityB extends BaseActivity implements InterfaceB;
...

在每个 Activity 中,我都有这样的方法(其中 X 是 A、B、C、... 对于每个 Activity ):

public void initActivity() {
ComponentX compX;
...
compX = appComponent.plus(new ModuleX(this)); // this == InterfaceX
...
compX.inject(this); // this == ActivityX
}

我试图减少这段代码,将其移至父 BaseActivity。但是我在做这件事时遇到了一些问题。我认为也许使用泛型我可以做到,但我不知 Prop 体怎么做。

最佳答案

问题是:哪个inject您正在调用的方法,Java 可以在编译时确定吗?

"A note about covariance" 中所述, Dagger 将为您定义的任何成员注入(inject)方法生成代码,但您传入的静态类型。

@Component public interface YourComponent {
void injectBase(BaseActivity baseActivity);
void injectA(ActivityA activityA);
void injectB(ActivityB activityB);
void injectC(ActivityC activityC);
}

调用injectA时并传递一个 ActivityA 实例,您将获得 ActivityA 中定义的字段的注入(inject),包括 BaseActivity 中的字段。与 ActivityB 和 ActivityC 相同。但是,如果您调用 injectBase ,Dagger只会注入(inject)属于BaseActivity的字段,即使你传入的对象恰好是一个ActivityA,ActivityB,或者ActivityC。 Dagger 在编译时生成代码,所以如果你调用 injectBase ,注入(inject)只会发生在 BaseActivity 上的字段上——因为这是为 BaseActivity 的成员注入(inject)器生成的代码,而这些是 Dagger 唯一知道如何为 BaseActivity 参数注入(inject)的字段。

自然是因为BaseActivity只知道this是BaseActivity的子类型,只能调用injectBase而不是任何特定的子类型。重要的是,即使所有名称 injectBase , injectA等等,都是一样的(比如 inject)。 JVM 将选择它在编译时可以确定的最窄重载,即 inject(BaseActivity)。 ,这将注入(inject) BaseActivity 的字段,而不会注入(inject)子类型。如果您要为它们命名,您会看到您调用的是哪一个,以及为什么它不注入(inject)子类型字段。

泛型在这里无济于事:您正在寻找组件来生成和调用 ActivityA、ActivityB 和 ActivityC 的成员注入(inject)器。泛型将被删除,但此外组件不能采用 BaseActivity 的任意子类:Dagger 不能在编译时为它可能只在运行时遇到的类型生成代码。您确实需要在编译时在 Dagger 中准备这些类型。

解决此问题的一种方法是允许子类型自行注入(inject)。子类型知道 this是 ActivityA(等等),即使代码看起来每个字符都相同,Java 也可以识别正确的类型并正确编译它。

// in BaseActivity
protected abstract void injectDependencies();

// in ActivityA
@Override protected void injectDependencies() { component.injectA(this); }

但是,还有另一个最近发布的选项,使用 dagger.android ,它使用多重绑定(bind)和(有效地)一个 Map<Class, MembersInjector> 动态注入(inject)你想要的特定类型。这也适用于父类(super class),以至于您可以让 Activity 扩展 DaggerActivity,一切都会按照您喜欢的方式工作。 (请参阅 dagger.android.support 包以了解您的 AppCompatActivity 等效项 DaggerAppCompatActivity。)

关于带有 BaseActivity 的 Android Dagger 2 可以减少样板文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43020736/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com