如何在Android库项目中使用Dagger

58
我目前正在尝试将Dagger添加到我的Android项目中。对于应用程序项目,我知道如何构建ObjectGraph,但是我不太清楚在Android库项目中应该如何构建ObjectGraph。我应该继续在应用程序的Application类中构建ObjectGraph并将OG传递给LibraryModule - 将Library的OG加到应用程序的OG中?还是应该在库中构建整个ObjectGraph?
如果我需要通过ObjectGraph.inject(this)在库中注入类,应该怎么办?在我的应用程序项目中,我可以从Application类获取OG。但是在库中如何处理?我应该为ObjectGraph添加一个@Provides方法吗?
非常感谢您的帮助。
简而言之:我如何在库中调用ObjectGraph.inject(this),因为无法访问由Application Class构建的OG?

4
我也有这个问题... 有人真的知道该怎么做吗? - mato
1
@sebastian,你解决了你的问题吗?如果是的话,请发布你的解决方案。 - Sachin
1
我在Dagger 2中卡住了。 - conca
你的库不应该从属于它的父级对象图中被注入。否则它就不再是一个库了。库不依赖于它的父级。你可以考虑创建一些基础/核心模块,其中包含你的库可以依赖的对象图。 - gjsalot
卡在这里好几个小时了,有人能帮我吗? - Himanshu
3个回答

36

如果有人在使用Dagger 2时遇到这个问题,这是我在我的应用中所做的方式:

在库模块中,我创建了以下Module和Component:

@Module
public class ModuleUtil {

    @Provides
    public RestTemplate provideRestTemplate() {
        return new RestTemplate();
    }

}

@Singleton
@Component(
        modules = {
                ModuleUtil.class
        })
public interface MainComponent {
    void inject(Postman postman);
}

接着我创建了下面这个单例来管理注入:

public class DaggerWrapper {

    private static MainComponent mComponent;

    public static MainComponent getComponent() {
        if (mComponent == null) {
            initComponent();
        }
        return mComponent;
    }

    private static void initComponent () {
       mComponent = DaggerMainComponent
                .builder()
                .utilModule(new ModuleUtil())
                .build();
    }
}

当库模块中的某个类需要注入其成员时,我只需调用 DaggerWrapper.getComponent().inject(this); 就可以了。


我了解DaggerWrapper也在您的库模块中,并且可以从您的应用程序模块访问。这是正确的吗? - Sebas LG
这似乎是一个更好的答案,因为它不需要应用程序(库的客户端)做任何事情。 - Peter Tran
有人能用吗?我按照相同的过程操作但无法运行。在构建应用程序时,我遇到了“找不到符号类DaggerMainComponent”的错误。 - Tejas Mehta
你尝试过使用dagger-android库来简化设置吗:https://google.github.io/dagger/android.html - IgorGanapolsky
这里的RestTemplate是什么?你能分享一些你可能已经实现了它的示例代码吗?对我来说不起作用。 - Himanshu
显示剩余3条评论

12

我正在这样做:

  1. @Module 类属于主项目,它们提供你注入到库元素中的实现,因此在库项目中没有 @Module 类。

  2. 期望依赖项的库元素必须能够访问 ObjectGraph 并在自己身上调用 .inject(),但主项目应该使用提供的 @Module 依赖项向库提供 ObjectGraph 实例。

  3. 如何将来自主项目的 ObjectGraph 传递到库中?你可以有一个像这样的接口:

    interface Injector {
        void inject(Object object);
        public ObjectGraph getObjectGraph(); 
    }

这个接口由像Activity或Application类这样的上下文对象实现(它们是ObjectGraph对象的持有者)。

如果你在库模块中有一个需要从主项目注入某些内容的Activity示例,代码应该是这样的:

class LibraryActivity extends Activity {

    @Inject ActivationModule instance;

    void onCreate(... ) {
        Injector injector = (Injector)getApplicationContext();
        injector.inject(this)
    }
}

ActivationModule 是库项目中的类/接口。

主项目有应用程序类,它实现了注入器接口并为库项目中的 ActivationModule 创建提供的依赖项的 ObjectGraph。

class MyApplicationInTheMainProject extends Application implements Injector {

    ObjectGraph graph;

    @Override
    public void onCreate() {
        super.onCreate();
        graph = ObjectGraph.create(new ActivationModuleImpl(this));
    }

    @Override public void inject(Object object) {
        graph.inject(object);
    }

    @Override public ObjectGraph getObjectGraph() {
        return graph;
    }
}


@Module(injects = {
        LibraryActivity.class
}, library = true)
class ActivationModuleImpl implements ActivationModule {
    ....
}

6
如果您要将此库提供给不了解您的情况的人,那么您必须以一种方式编写它,使得您的Dagger可以在没有用户帮助的情况下完美运行。(越容易使用越好的实践)
我为您编写了一些库以展示如何操作。我以这样一种方式编写库,即您甚至可以独立运行它并在消息选项卡中查看结果。您的库用户不需要知道任何关于Dagger的信息,并且不需要进行任何操作,只需使用库,Dagger将被配置:

https://github.com/amirziaratii/libraryUsingDagger.git

如果这个库是你自己使用的并且用于你自己的项目,最佳实践是像我朋友的这个项目一样做:

https://github.com/mmirhoseini/trakt.tv

所有问题都可以在这两个项目中找到答案。任何问题都可以在评论中提出,我会回答。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接