Java 如何正确使用匕首2';用LibGDX进行s场注入?
我在基于LibGDX的游戏中注入一些依赖项时遇到问题。 谁能告诉我我错过了什么 我有两个模块 首先提供Android的Java 如何正确使用匕首2';用LibGDX进行s场注入?,java,android,dependency-injection,libgdx,dagger-2,Java,Android,Dependency Injection,Libgdx,Dagger 2,我在基于LibGDX的游戏中注入一些依赖项时遇到问题。 谁能告诉我我错过了什么 我有两个模块 首先提供Android的上下文: @Module public class AppModule { Context context; public AppModule(Context context) { this.context = context; } @Provides @Singleton Context providesCon
上下文
:
@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);
}
现在,我添加了自定义应用程序类(在清单中定义),我在其中实例化了我的组件:
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安卓的启动器中,在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
方法
我的菜单屏幕
类:
public class MenuScreen extends ScreenAdapter {
@Inject AnalyticsUtils analyticsUtils;
public MenuScreen(GameName game) {
// Some initialization.
useAnalytics();
}
private void useAnalytics() {
analyticsUtils.someMethod();
}
}
如上所述,在MenuScreen
class中,我想使用字段注入注入AnalyticsUtils
class
在构造函数中,我调用一个使用analyticsUtils
对象的方法并调用它的方法
在该行中,我正在调用analyticsUtils.someMethod()
我正在获取和NullPointerExcetion
(尝试在null
对象上调用.someMethod()
)
我是否应该在注入任何内容的每个类中使用组件的inject()
方法(无论使用字段/构造函数注入)
我已经阅读了很多Dagger的教程和文档,但是每个可用的示例都很简单(大多数情况下,它们显示了活动中的简单注入)
经过几个小时的尝试,我决定我需要找一个在匕首方面更有经验的人。我很乐意提供任何提示和/或资源。注释本身不会起任何作用-
MenuScreen
不提供其依赖项
尽可能使用构造函数注入。
字段注入将由活动和片段使用,因为您不能修改/使用它们的构造函数。除了一些罕见的情况外,您应该尽可能使用构造函数注入
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();
}
}
如果可以提供所有依赖项,这将起作用
使用匕首意味着你不应该自己叫construcors
((GameApplication) getApplication()).getGameComponent().inject(this);
initialize(new GameName());
GameName
显然应该从GameComponent
提供
如果可以只提供类,则不要使用模块
@Provides
@Singleton
AnalyticsUtils providesAnalyticsUtils(Context context) {
return new AnalyticsUtils(context);
}
你不需要这些。使用@Singleton
注释类分析工具
,使用@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);
}
事实上,我的
MenuScreen
类(以及许多其他类)使用了我想要注入的更多依赖项。我想我应该用多个参数创建这样糟糕的构造函数,还是创建包含其他对象的包装类?这就是为什么我想使用字段注入的原因。@ TimMUS我会考虑“包含其他对象的包装类”作为反模式。如果一个类有太多的依赖项,这可能意味着它做的太多了。然后,你应该将它的一些特性提取到其他类中。是的,我在发表我的评论后,已经考虑过这一点。此外,感谢您的回复。我认为你的答案是正确的。它让我对这个话题有了一些了解,并改变了我对Dagger的观点和理解(尤其是依赖于缺乏模块使用要求的快捷方式)。