java - 如何在 LibGDX 中正确使用 Dagger 2 的场注入(inject)?

标签 java android dependency-injection libgdx dagger-2

我在基于 LibGDX 的游戏中注入(inject)一些依赖项时遇到问题。 谁能指出我缺少的东西?

我有两个模块。

首先提供Android的Context:

@Module
public class AppModule {
    Context context;

    public AppModule(Context context) {
        this.context = context;
    }

    @Provides
    @Singleton
    Context providesContext() {
        return context;
    }
} 

第二个提供与 Google Analytics 交互的类:

@Module
public class ServicesModule {
    @Provides
    @Singleton
    AnalyticsUtils providesAnalyticsUtils(Context context) {
        return new AnalyticsUtils(context);
    }
}

我的组件类是这样实现的:

@Singleton
@Component(modules = {AppModule.class, ServicesModule.class})
public interface GameComponent {
    void inject(Launcher launcher);
}

现在,我在实例化我的组件的地方添加了自定义应用程序类(在 list 中定义):

public class GameApplication extends Application {
    private GameComponent gameComponent;

    @Override
    public void onCreate() {
        super.onCreate();

        gameComponent = DaggerGameComponent.builder()
            .appModule(new AppModule(this))
            .servicesModule(new ServicesModule())
            .build();
    }

    public GameComponent getGameComponent() {
        return gameComponent;
    }
}

在 LibGDX And​​roid 的启动器中,在 onCreate 方法中我调用组件的 inject() 方法:

public class Launcher extends AndroidApplication {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        ((GameApplication) getApplication()).getGameComponent().inject(this);

        initialize(new GameName());
    }
}

假设 GameName 是一个扩展 LibGDX 的 Game 类的类。在它的 create 方法中,我调用了启动我的菜单屏幕的 setScreen 方法。

我的 MenuScreen 类:

public class MenuScreen extends ScreenAdapter {
    @Inject AnalyticsUtils analyticsUtils;

    public MenuScreen(GameName game) {
        // Some initialization.
        useAnalytics();
    }

    private void useAnalytics() {
        analyticsUtils.someMethod();
    }
}

如上所述,在 MenuScreen 类中,我想使用字段注入(inject)来注入(inject) AnalyticsUtils 类。

在构造函数中,我正在调用一个使用 analyticsUtils 对象的方法并调用它的方法。

在我调用 analyticsUtils.someMethod() 的那一行,我得到了 NullPointerExcetion(试图调用 .someMethod()null 对象上)。

我是否应该在每个要注入(inject)任何东西的类中使用组件的 inject() 方法(无论使用字段/构造函数注入(inject))?

我已经阅读了很多 Dagger 的教程和文档,但是每个可用的示例都很简单(大多数情况下,它们显示了 Activity 中的简单注入(inject))。

经过几个小时的尝试,我决定我需要请教对 Dagger 更有经验的人。如果有任何提示和/或资源,我将很高兴。

最佳答案

注解本身不会做任何事情——MenuScreen 没有提供它的依赖项。

尽可能使用构造函数注入(inject)。

字段注入(inject)将由 Activity 和 fragment 使用,因为您不能修改/使用它们的构造函数。除了一些罕见的情况,您应该尽可能使用构造函数注入(inject)。

public class MenuScreen extends ScreenAdapter {
    private final AnalyticsUtils analyticsUtils;

    @Inject 
    public MenuScreen(GameName game, AnalyticsUtils analyticsUtils) {
        this.analyticsUtils = analyticsUtils;
        // Some initialization.
        useAnalytics();
    }

    private void useAnalytics() {
        analyticsUtils.someMethod();
    }
}

如果可以提供所有依赖项,这将起作用。

使用 dagger 意味着你应该自己调用构造函数

((GameApplication) getApplication()).getGameComponent().inject(this);

initialize(new GameName());

GameName 应该显然GameComponent 提供。

如果只能提供类就不要使用模块

@Provides
@Singleton
AnalyticsUtils providesAnalyticsUtils(Context context) {
    return new AnalyticsUtils(context);
}

你不需要这些。用@Singleton注解class AnalyticsUtils,用@Inject注解其构造函数,即可提供。 没有任何模块。这就是构造函数注入(inject)。

使用注入(inject)

你没有提供太多关于你在哪里做什么的背景信息。但是如果可以提供GameName,就可以构建MenuScreen。你可以例如只需执行以下操作

@Inject
GameName mGame;
@Inject
MenuScreen mMenu;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    ((GameApplication) getApplication()).getGameComponent().inject(this);

    initialize(mGame);
}

关于java - 如何在 LibGDX 中正确使用 Dagger 2 的场注入(inject)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35904510/

相关文章:

java - 如何使用 Log4J 设置我的 BlazeDS 实现?

java - 使用 Android Studio 从 SharedPreferences 的 Arraylist 中删除项目

java - Spring 错误 : BeanNotOfRequiredTypeException

javascript - 协作 coffeescript 服务/类(class)

java - 从服务器返回任何错误响应的 FTP 上传代码

java - 随机数方法的 Junit 测试

java - 运行自定义 TextSecure(信号)服务器

android - 实时编码音频会导致听得见的跳音

java - 安卓相机: Save preview frames to buffer?

spring - Spring和javax.enterprise.inject有什么关系?