【问题标题】:Exposing Dagger Components defined in an Android Library暴露在 Android 库中定义的 Dagger 组件
【发布时间】:2019-08-30 04:30:09
【问题描述】:

一个 gradle 模块中的 Android 应用程序如何包含在另一个 Android 库 (.aar) 中定义的 dagger @Modules?

我正在尝试拥有一个通用库,它提供一组通过 dagger @Module 定义的功能,能够将它们注入到依赖于该库的应用程序中

@Singleton
@Component(modules = {
        AndroidSupportInjectionModule.class,
        LibraryAppModule.class
})
public interface LibraryComponent extends AndroidInjector<DaggerApplication> {
    @Component.Builder
    interface Builder {
        @BindsInstance
        Builder application(Application application);
        LibraryComponent build();
    }

    void inject(LibraryApplication app);

    @Override
    void inject(DaggerApplication instance);
}
@Module
public class LibraryAppModule {

    @Provides
    @Singleton
    Context provideContext(Application application) {
        return application;
    }

    @Singleton
    @Provides
    ServiceFoo provideServiceFoo(Context context) {
        return new ServiceFoo(context);
    }

    @Singleton
    @Provides
    ServiceBar provideServiceBar(Context context, ServiceFoo serviceFoo) {
        return new ServiceBar(context, serviceFoo);
    }

}

现在,在依赖于该库的应用程序 (build.gradle) 中,我尝试了以下方法:

implementation project(":Library")

使用库的应用程序

@Singleton
@Component(modules = {
        AndroidSupportInjectionModule.class,
        LibraryAppModule.class
})
public interface ExampleApplicationComponent extends AndroidInjector<DaggerApplication> {

    @Component.Builder
    interface Builder {
        @BindsInstance
        Builder application(Application application);
        ExampleApplicationComponent build();
    }

    void inject(ExampleApplication app);

    @Override
    void inject(DaggerApplication instance);
}

这是我遇到问题的地方的一个例子(一个空对象)。这是在依赖于库的单独模块中。

public class MainActivity extends AppCompatActivity {

    @Inject
    ServiceFoo serviceFoo;

    @Inject
    ServiceBar serviceBar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        serviceFoo.downloadImages();

        serviceBar.uploadImages();
    }
}

我希望看到 LibraryAppModule 的服务在我使用 @Inject 的活动中可用。我做错了什么?

【问题讨论】:

  • 你能发布错误吗?
  • 我已经创建了一个示例项目来突出这个问题:github.com/PeregrineFalcon/DaggerExampleLibrary 如果你在 MainActivity.java:25 设置一个断点,你会看到 serviceFoo 和 serviceBar 都是 null 并且没有注入/实例化。

标签: android dagger-2 aar


【解决方案1】:

为了解决这个问题,需要做两件事。

  1. MainActivity 必须扩展 DaggerAppCompatActivity(这可确保在我们的 Activity 的 onCreate() 期间调用 inject(),但要使其正常工作,需要为 Activity 提供 AndroidInjector
  2. 这是通过在我定义并安装到ExampleApplicationComponent 的模块中使用@ContributesAndroidInjector 来完成的
@Module
public abstract class ExampleApplicationActivityBuilder {

    @ContributesAndroidInjector
    abstract MainActivity bindMainActivity();
}

现在在MainActivity 中,我想从库模块注入的服务是非空的。

这是一个 git 提交,显示了实现此修复的不同之处。 https://github.com/PeregrineFalcon/DaggerExampleLibrary/commit/1ebfdecfa3684c7ac124b9f6a4cecd23712a74fd

希望这可以帮助其他尝试使用通过库提供的@Modules 进行多模块 Dagger Android 项目的人。

【讨论】:

  • 我在下面给出的答案也可以,但需要您在 Activity 中创建一个额外的构建器。您使用 AndroidInjector 的方法更好,因为它避免了代码重复。
【解决方案2】:

想要注入属性的类应该调用inject()

既然你想将serviceFoo 注入MainActivity,你应该从onCreate() 调用inject()。但是,inject() 是在哪里定义的,您可以直接调用它吗?因此,您还要在 ExampleApplicationComponent 中声明 inject()

说了这么多,看来你对匕首的理解是不完整的。推荐this博文。

【讨论】:

  • 我会阅读这篇文章。谢谢。话虽如此,注入调用是我扩展 DaggerApplication 事实的一部分,但我确实注意到我的 MainActivity 没有扩展 DaggerCompatActivity 将修复并查看是否有帮助。
猜你喜欢
  • 1970-01-01
  • 2018-09-17
  • 2015-07-26
  • 1970-01-01
  • 1970-01-01
  • 2021-10-10
  • 1970-01-01
  • 1970-01-01
  • 2016-11-11
相关资源
最近更新 更多