我有两个模块:AndroidModule
用于提供Context
相关对象,PhotosModule
提供PhotoManager
。
我想在PhotoManager
中使用PhotosFragment
。 PhotoManager
取决于由DbManager
提供的AndroidModule
。
如何连接所有点?
代码编译,但NPE被抛出这一行:
mDbManager.readDatabase();
意味着DbManager
注入PhotoManager
并未发生,即使我设置了
injects = PhotoManager.class
AndroidModule
中的。
此外,mDbManager
不是私有字段,所以我认为我不必在PhotoManager
的构造函数上使用注入;现场注射应该足够了。
是什么原因以及如何满足缺失的依赖?我假设我的代码可能有多个问题。注意:我刚开始使用Dagger,请记住这一点。
应用:
public class TestApp extends Application {
private ObjectGraph mObjectGraph;
@Override
public void onCreate() {
super.onCreate();
mObjectGraph = ObjectGraph.create(getModules().toArray());
}
protected List<Object> getModules() {
return Arrays.asList(new AndroidModule(this), new PhotosModule());
}
public void inject(Object object) {
mObjectGraph.inject(object);
}
}
AndroidModule:
@Module(library = true, injects = PhotoManager.class)
public class AndroidModule {
private final TestApp mApplication;
public AndroidModule(TestApp application) {
mApplication = application;
}
@Provides
@Singleton
@ForApplication
Context provideApplicationContext() {
return mApplication;
}
@Provides
@Singleton
DbManager provideDbManager() {
return new DbManager(mApplication);
}
}
PhotosModule:
@Module(injects = PhotosFragment.class)
public class PhotosModule {
@Provides
@Singleton
PhotoManager providePhotoManager() {
return new PhotoManager();
}
}
PhotoManager:
@Singleton
public class PhotoManager {
@Inject
DbManager mDbManager;
public void doSomething() {
mDbManager.readDatabase();
}
}
PhotosFragment:
public class PhotosFragment extends Fragment {
@Inject
PhotoManager mPhotoManager;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
((TestApp) getActivity().getApplication()).inject(this);
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
///...
mPhotoManager.doSomething();
}
}
DbManager:
@Singleton
public class DbManager {
public DbManager(Context context) {
//...
}
public void readDatabase() {
//...
}
}
答案 0 :(得分:2)
这是问题的核心:在PhotosModule
中,您有提供者方法:
PhotoManager providePhotoManager() {
return new PhotoManager();
}
您自己new
了PhotoManager,因此Dagger没有机会注入其依赖关系(DbManager
)。
我认为这是因为您误解了injects
@Module(injects=...)
注释中AndroidModule
属性的含义。你有:
@Module(library = true, injects = PhotoManager.class)
但是injects
并不需要,因为你永远不会在PhotoManager上调用objectGraph.inject。相反,您只是注入PhotoFragment
,这是正确的......
解决NPE问题的一种方法是:
从injects=PhotoManager.class
AndroidModule.java
@Module(library = true)
更改PhotosModule
以包含AndroidModule
:
@Module(injects = PhotosFragment.class, includes = AndroidModule.class)
我使用@Inject
注释避免了字段注入(仅用于顶层对象,即你在objectgraph.inject中的位置,例如活动和片段级别),并使用构造函数注入相反,所有其他依赖项。所以我要更改PhotoManager
以注入DbManager
,如下所示:
private final DbManager mDbManager;
public PhotoManager(DbManager dbManager) {
mDbManager = dbManager;
}
我已经提出了代码here on GitHub。